1
1
use crate :: context:: LintContext ;
2
- use crate :: lints:: { NoopMethodCallDiag , SuspiciousDoubleRefDiag } ;
2
+ use crate :: lints:: {
3
+ NoopMethodCallDiag , SuspiciousDoubleRefCloneDiag , SuspiciousDoubleRefDerefDiag ,
4
+ } ;
3
5
use crate :: LateContext ;
4
6
use crate :: LateLintPass ;
5
7
use rustc_hir:: def:: DefKind ;
@@ -76,22 +78,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
76
78
77
79
// We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow`
78
80
// 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 ;
94
95
} ;
96
+
95
97
let substs = cx
96
98
. tcx
97
99
. normalize_erasing_regions ( cx. param_env , cx. typeck_results ( ) . node_substs ( expr. hir_id ) ) ;
@@ -102,13 +104,6 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
102
104
// (Re)check that it implements the noop diagnostic.
103
105
let Some ( name) = cx. tcx . get_diagnostic_name ( i. def_id ( ) ) else { return } ;
104
106
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
-
112
107
let receiver_ty = cx. typeck_results ( ) . expr_ty ( receiver) ;
113
108
let expr_ty = cx. typeck_results ( ) . expr_ty_adjusted ( expr) ;
114
109
let arg_adjustments = cx. typeck_results ( ) . expr_adjustments ( receiver) ;
@@ -129,11 +124,22 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
129
124
NoopMethodCallDiag { method : call. ident . name , receiver_ty, label : span } ,
130
125
) ;
131
126
} 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
+ }
137
143
}
138
144
}
139
145
}
0 commit comments