11use crate :: context:: LintContext ;
2- use crate :: lints:: { NoopMethodCallDiag , SuspiciousDoubleRefDiag } ;
2+ use crate :: lints:: {
3+ NoopMethodCallDiag , SuspiciousDoubleRefCloneDiag , SuspiciousDoubleRefDerefDiag ,
4+ } ;
35use crate :: LateContext ;
46use crate :: LateLintPass ;
57use rustc_hir:: def:: DefKind ;
@@ -76,22 +78,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
7678
7779 // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
7880 // traits and ignore any other method call.
79- let did = match cx. typeck_results ( ) . type_dependent_def ( expr. hir_id ) {
80- // Verify we are dealing with a method/associated function.
81- Some ( ( DefKind :: AssocFn , did) ) => match cx. tcx . trait_of_item ( did) {
82- // Check that we're dealing with a trait method for one of the traits we care about.
83- Some ( trait_id)
84- if matches ! (
85- cx. tcx. get_diagnostic_name( trait_id) ,
86- Some ( sym:: Borrow | sym:: Clone | sym:: Deref )
87- ) =>
88- {
89- did
90- }
91- _ => return ,
92- } ,
93- _ => return ,
81+
82+ let Some ( ( DefKind :: AssocFn , did) ) =
83+ cx. typeck_results ( ) . type_dependent_def ( expr. hir_id )
84+ else {
85+ return ;
86+ } ;
87+
88+ let Some ( trait_id) = cx. tcx . trait_of_item ( did) else { return } ;
89+
90+ if !matches ! (
91+ cx. tcx. get_diagnostic_name( trait_id) ,
92+ Some ( sym:: Borrow | sym:: Clone | sym:: Deref )
93+ ) {
94+ return ;
9495 } ;
96+
9597 let substs = cx
9698 . tcx
9799 . normalize_erasing_regions ( cx. param_env , cx. typeck_results ( ) . node_substs ( expr. hir_id ) ) ;
@@ -102,13 +104,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
102104 // (Re)check that it implements the noop diagnostic.
103105 let Some ( name) = cx. tcx . get_diagnostic_name ( i. def_id ( ) ) else { return } ;
104106
105- let op = match name {
106- sym:: noop_method_borrow => "borrow" ,
107- sym:: noop_method_clone => "clone" ,
108- sym:: noop_method_deref => "deref" ,
109- _ => return ,
110- } ;
111-
112107 let receiver_ty = cx. typeck_results ( ) . expr_ty ( receiver) ;
113108 let expr_ty = cx. typeck_results ( ) . expr_ty_adjusted ( expr) ;
114109 let arg_adjustments = cx. typeck_results ( ) . expr_adjustments ( receiver) ;
@@ -129,11 +124,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
129124 NoopMethodCallDiag { method : call. ident . name , receiver_ty, label : span } ,
130125 ) ;
131126 } else {
132- cx. emit_spanned_lint (
133- SUSPICIOUS_DOUBLE_REF_OP ,
134- span,
135- SuspiciousDoubleRefDiag { call : call. ident . name , ty : expr_ty, op } ,
136- )
127+ match name {
128+ // If `type_of(x) == T` and `x.borrow()` is used to get `&T`,
129+ // then that should be allowed
130+ sym:: noop_method_borrow => return ,
131+ sym:: noop_method_clone => cx. emit_spanned_lint (
132+ SUSPICIOUS_DOUBLE_REF_OP ,
133+ span,
134+ SuspiciousDoubleRefCloneDiag { ty : expr_ty } ,
135+ ) ,
136+ sym:: noop_method_deref => cx. emit_spanned_lint (
137+ SUSPICIOUS_DOUBLE_REF_OP ,
138+ span,
139+ SuspiciousDoubleRefDerefDiag { ty : expr_ty } ,
140+ ) ,
141+ _ => return ,
142+ }
137143 }
138144 }
139145}
0 commit comments