@@ -5,7 +5,7 @@ use clippy_utils::macros::{root_macro_call_first_node, MacroCall};
55use rustc_hir:: { Expr , ExprKind , QPath , TyKind } ;
66use rustc_lint:: { LateContext , LateLintPass } ;
77use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
8- use rustc_span:: sym;
8+ use rustc_span:: { sym, Symbol } ;
99
1010declare_clippy_lint ! {
1111 /// ### What it does
@@ -37,43 +37,46 @@ impl LateLintPass<'_> for ArcNewInVecFromElem {
3737 let Some ( macro_call) = root_macro_call_first_node ( cx, expr) else { return ; } ;
3838
3939 if let Some ( VecArgs :: Repeat ( elem, _) ) = VecArgs :: hir ( cx, expr) {
40- if !is_arc_new ( cx, elem) {
41- return ;
42- }
40+ let Some ( symbol) = new_reference_call ( cx, elem) else { return ; } ;
4341
44- yield_lint ( cx, & macro_call) ;
42+ yield_lint ( cx, symbol , & macro_call) ;
4543 }
4644 }
4745}
4846
49- fn yield_lint ( cx : & LateContext < ' _ > , macro_call : & MacroCall ) {
47+ fn yield_lint ( cx : & LateContext < ' _ > , symbol : Symbol , macro_call : & MacroCall ) {
48+ let symbol_name = symbol. as_str ( ) ;
49+
5050 span_lint_and_then (
5151 cx,
5252 ARC_NEW_IN_VEC_FROM_ELEM ,
5353 macro_call. span ,
54- "calling `Arc ::new` in `vec![elem; len]`" ,
54+ & format ! ( "calling `{symbol_name} ::new` in `vec![elem; len]`" ) ,
5555 |diag| {
56- diag. note ( "each `Arc` will point to the same allocation" ) ;
57- diag. help ( "if this is intentional, consider extracting the `Arc` initialization to a variable" ) ;
56+ diag. note ( format ! ( "each `{symbol_name}` will point to the same allocation" ) ) ;
57+ diag. help ( format ! (
58+ "if this is intentional, consider extracting the `{symbol_name}` initialization to a variable"
59+ ) ) ;
5860 } ,
5961 ) ;
6062}
6163
62- /// Checks whether the given `expr` is a call to `Arc::new`
63- fn is_arc_new ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
64+ /// Checks whether the given `expr` is a call to `Arc::new` or `Rc::new`
65+ fn new_reference_call ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> Option < Symbol > {
6466 if_chain ! {
6567 if let ExprKind :: Call ( func, _args) = expr. kind;
6668 if let ExprKind :: Path ( ref func_path @ QPath :: TypeRelative ( ty, _) ) = func. kind;
6769 if let TyKind :: Path ( ref ty_path) = ty. kind;
6870 if let Some ( def_id) = cx. qpath_res( ty_path, ty. hir_id) . opt_def_id( ) ;
69- if cx . tcx . is_diagnostic_item ( sym:: Arc , def_id ) ;
71+ if last_path_segment ( func_path ) . ident . name == sym:: new ;
7072
7173 then {
72- let func_segment = last_path_segment( func_path) ;
73-
74- return func_segment. ident. name == sym:: new;
74+ return match cx. tcx. get_diagnostic_name( def_id) {
75+ Some ( symbol) if symbol == sym:: Arc || symbol == sym:: Rc => Some ( symbol) ,
76+ _ => None
77+ } ;
7578 }
7679 }
7780
78- false
81+ None
7982}
0 commit comments