@@ -91,67 +91,56 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
9191 // And that it only has one argument.
9292 && let [ arg] = args
9393 {
94- match arg. kind {
95- hir:: ExprKind :: Closure ( & hir:: Closure { body, .. } ) => {
96- // If it's a closure, we need to check what is called.
97- let closure_body = cx. tcx . hir ( ) . body ( body) ;
98- let closure_expr = peel_blocks ( closure_body. value ) ;
99- match closure_expr. kind {
100- hir:: ExprKind :: MethodCall ( method, obj, [ ] , _) => {
101- if method. ident . name == sym:: clone
102- && let Some ( fn_id) = cx. typeck_results ( ) . type_dependent_def_id ( closure_expr. hir_id )
103- && let Some ( trait_id) = cx. tcx . trait_of_item ( fn_id)
104- // We check it's the `Clone` trait.
105- && cx. tcx . lang_items ( ) . clone_trait ( ) . map_or ( false , |id| id == trait_id)
106- // no autoderefs
107- && !cx. typeck_results ( ) . expr_adjustments ( obj) . iter ( )
108- . any ( |a| matches ! ( a. kind, Adjust :: Deref ( Some ( ..) ) ) )
109- {
110- lint_as_ref_clone ( cx, expr. span . with_hi ( parent. span . hi ( ) ) , recvr, call_name) ;
111- }
112- } ,
113- hir:: ExprKind :: Call ( call, [ _] ) => {
114- if let hir:: ExprKind :: Path ( qpath) = call. kind {
115- check_qpath (
116- cx,
117- expr. span . with_hi ( parent. span . hi ( ) ) ,
118- recvr,
119- call_name,
120- qpath,
121- call. hir_id ,
122- ) ;
123- }
124- } ,
125- _ => { } ,
126- }
127- } ,
128- hir:: ExprKind :: Path ( qpath) => check_qpath (
129- cx,
130- expr. span . with_hi ( parent. span . hi ( ) ) ,
131- recvr,
132- call_name,
133- qpath,
134- arg. hir_id ,
135- ) ,
136- _ => { } ,
94+ if is_calling_clone ( cx, arg) {
95+ lint_as_ref_clone ( cx, expr. span . with_hi ( parent. span . hi ( ) ) , recvr, call_name) ;
13796 }
13897 }
13998 }
14099}
141100
142- fn check_qpath (
143- cx : & LateContext < ' _ > ,
144- span : Span ,
145- recvr : & hir:: Expr < ' _ > ,
146- call_name : & str ,
147- qpath : hir:: QPath < ' _ > ,
148- hir_id : hir:: HirId ,
149- ) {
101+ fn check_qpath ( cx : & LateContext < ' _ > , qpath : hir:: QPath < ' _ > , hir_id : hir:: HirId ) -> bool {
150102 // We check it's calling the `clone` method of the `Clone` trait.
151- if let Some ( path_def_id) = cx. qpath_res ( & qpath, hir_id) . opt_def_id ( )
152- && match_def_path ( cx, path_def_id, & paths:: CLONE_TRAIT_METHOD )
153- {
154- lint_as_ref_clone ( cx, span, recvr, call_name) ;
103+ if let Some ( path_def_id) = cx. qpath_res ( & qpath, hir_id) . opt_def_id ( ) {
104+ match_def_path ( cx, path_def_id, & paths:: CLONE_TRAIT_METHOD )
105+ } else {
106+ false
107+ }
108+ }
109+
110+ fn is_calling_clone ( cx : & LateContext < ' _ > , arg : & hir:: Expr < ' _ > ) -> bool {
111+ match arg. kind {
112+ hir:: ExprKind :: Closure ( & hir:: Closure { body, .. } ) => {
113+ // If it's a closure, we need to check what is called.
114+ let closure_body = cx. tcx . hir ( ) . body ( body) ;
115+ let closure_expr = peel_blocks ( closure_body. value ) ;
116+ match closure_expr. kind {
117+ hir:: ExprKind :: MethodCall ( method, obj, [ ] , _) => {
118+ if method. ident . name == sym:: clone
119+ && let Some ( fn_id) = cx. typeck_results ( ) . type_dependent_def_id ( closure_expr. hir_id )
120+ && let Some ( trait_id) = cx. tcx . trait_of_item ( fn_id)
121+ // We check it's the `Clone` trait.
122+ && cx. tcx . lang_items ( ) . clone_trait ( ) . map_or ( false , |id| id == trait_id)
123+ // no autoderefs
124+ && !cx. typeck_results ( ) . expr_adjustments ( obj) . iter ( )
125+ . any ( |a| matches ! ( a. kind, Adjust :: Deref ( Some ( ..) ) ) )
126+ {
127+ true
128+ } else {
129+ false
130+ }
131+ } ,
132+ hir:: ExprKind :: Call ( call, [ _] ) => {
133+ if let hir:: ExprKind :: Path ( qpath) = call. kind {
134+ check_qpath ( cx, qpath, call. hir_id )
135+ } else {
136+ false
137+ }
138+ } ,
139+ _ => false ,
140+ }
141+ } ,
142+ hir:: ExprKind :: Path ( qpath) => check_qpath ( cx, qpath, arg. hir_id ) ,
143+ _ => false ,
155144 }
156145}
157146
0 commit comments