11use clippy_utils:: diagnostics:: span_lint_and_then;
22use clippy_utils:: source:: { indent_of, snippet} ;
33use clippy_utils:: { expr_or_init, get_attr, path_to_local, peel_hir_expr_unary} ;
4- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
4+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
55use rustc_errors:: Applicability ;
66use rustc_hir:: def:: { DefKind , Res } ;
77use rustc_hir:: intravisit:: { walk_expr, Visitor } ;
@@ -12,6 +12,7 @@ use rustc_session::impl_lint_pass;
1212use rustc_span:: symbol:: Ident ;
1313use rustc_span:: { sym, Span , DUMMY_SP } ;
1414use std:: borrow:: Cow ;
15+ use std:: collections:: hash_map:: Entry ;
1516
1617declare_clippy_lint ! {
1718 /// ### What it does
@@ -57,7 +58,6 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]);
5758pub struct SignificantDropTightening < ' tcx > {
5859 apas : FxIndexMap < HirId , AuxParamsAttr > ,
5960 /// Auxiliary structure used to avoid having to verify the same type multiple times.
60- seen_types : FxHashSet < Ty < ' tcx > > ,
6161 type_cache : FxHashMap < Ty < ' tcx > , bool > ,
6262}
6363
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
7474 self . apas . clear ( ) ;
7575 let initial_dummy_stmt = dummy_stmt_expr ( body. value ) ;
7676 let mut ap = AuxParams :: new ( & mut self . apas , & initial_dummy_stmt) ;
77- StmtsChecker :: new ( & mut ap, cx, & mut self . seen_types , & mut self . type_cache ) . visit_body ( body) ;
77+ StmtsChecker :: new ( & mut ap, cx, & mut self . type_cache ) . visit_body ( body) ;
7878 for apa in ap. apas . values ( ) {
7979 if apa. counter <= 1 || !apa. has_expensive_expr_after_last_attr {
8080 continue ;
@@ -142,28 +142,25 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
142142/// Checks the existence of the `#[has_significant_drop]` attribute.
143143struct AttrChecker < ' cx , ' others , ' tcx > {
144144 cx : & ' cx LateContext < ' tcx > ,
145- seen_types : & ' others mut FxHashSet < Ty < ' tcx > > ,
146145 type_cache : & ' others mut FxHashMap < Ty < ' tcx > , bool > ,
147146}
148147
149148impl < ' cx , ' others , ' tcx > AttrChecker < ' cx , ' others , ' tcx > {
150- pub ( crate ) fn new (
151- cx : & ' cx LateContext < ' tcx > ,
152- seen_types : & ' others mut FxHashSet < Ty < ' tcx > > ,
153- type_cache : & ' others mut FxHashMap < Ty < ' tcx > , bool > ,
154- ) -> Self {
155- seen_types. clear ( ) ;
156- Self {
157- cx,
158- seen_types,
159- type_cache,
160- }
149+ pub ( crate ) fn new ( cx : & ' cx LateContext < ' tcx > , type_cache : & ' others mut FxHashMap < Ty < ' tcx > , bool > ) -> Self {
150+ Self { cx, type_cache }
161151 }
162152
163153 fn has_sig_drop_attr ( & mut self , ty : Ty < ' tcx > ) -> bool {
164- // The borrow checker prevents us from using something fancier like or_insert_with.
165- if let Some ( ty) = self . type_cache . get ( & ty) {
166- return * ty;
154+ let ty = self
155+ . cx
156+ . tcx
157+ . try_normalize_erasing_regions ( self . cx . param_env , ty)
158+ . unwrap_or ( ty) ;
159+ match self . type_cache . entry ( ty) {
160+ Entry :: Occupied ( e) => return * e. get ( ) ,
161+ Entry :: Vacant ( e) => {
162+ e. insert ( false ) ;
163+ } ,
167164 }
168165 let value = self . has_sig_drop_attr_uncached ( ty) ;
169166 self . type_cache . insert ( ty, value) ;
@@ -185,7 +182,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
185182 rustc_middle:: ty:: Adt ( a, b) => {
186183 for f in a. all_fields ( ) {
187184 let ty = f. ty ( self . cx . tcx , b) ;
188- if ! self . has_seen_ty ( ty ) && self . has_sig_drop_attr ( ty) {
185+ if self . has_sig_drop_attr ( ty) {
189186 return true ;
190187 }
191188 }
@@ -205,32 +202,21 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
205202 _ => false ,
206203 }
207204 }
208-
209- fn has_seen_ty ( & mut self , ty : Ty < ' tcx > ) -> bool {
210- !self . seen_types . insert ( ty)
211- }
212205}
213206
214207struct StmtsChecker < ' ap , ' lc , ' others , ' stmt , ' tcx > {
215208 ap : & ' ap mut AuxParams < ' others , ' stmt , ' tcx > ,
216209 cx : & ' lc LateContext < ' tcx > ,
217- seen_types : & ' others mut FxHashSet < Ty < ' tcx > > ,
218210 type_cache : & ' others mut FxHashMap < Ty < ' tcx > , bool > ,
219211}
220212
221213impl < ' ap , ' lc , ' others , ' stmt , ' tcx > StmtsChecker < ' ap , ' lc , ' others , ' stmt , ' tcx > {
222214 fn new (
223215 ap : & ' ap mut AuxParams < ' others , ' stmt , ' tcx > ,
224216 cx : & ' lc LateContext < ' tcx > ,
225- seen_types : & ' others mut FxHashSet < Ty < ' tcx > > ,
226217 type_cache : & ' others mut FxHashMap < Ty < ' tcx > , bool > ,
227218 ) -> Self {
228- Self {
229- ap,
230- cx,
231- seen_types,
232- type_cache,
233- }
219+ Self { ap, cx, type_cache }
234220 }
235221
236222 fn manage_has_expensive_expr_after_last_attr ( & mut self ) {
@@ -288,7 +274,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o
288274 apa. counter = apa. counter . wrapping_add ( 1 ) ;
289275 apa. has_expensive_expr_after_last_attr = false ;
290276 } ;
291- let mut ac = AttrChecker :: new ( self . cx , self . seen_types , self . type_cache ) ;
277+ let mut ac = AttrChecker :: new ( self . cx , self . type_cache ) ;
292278 if ac. has_sig_drop_attr ( self . cx . typeck_results ( ) . expr_ty ( expr) ) {
293279 if let hir:: StmtKind :: Let ( local) = self . ap . curr_stmt . kind
294280 && let hir:: PatKind :: Binding ( _, hir_id, ident, _) = local. pat . kind
0 commit comments