1- use crate :: FxHashSet ;
21use clippy_utils:: {
32 diagnostics:: span_lint_and_then,
43 get_attr,
54 source:: { indent_of, snippet} ,
65} ;
6+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
77use rustc_errors:: { Applicability , Diagnostic } ;
88use rustc_hir:: {
99 self as hir,
@@ -58,6 +58,7 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]);
5858pub struct SignificantDropTightening < ' tcx > {
5959 /// Auxiliary structure used to avoid having to verify the same type multiple times.
6060 seen_types : FxHashSet < Ty < ' tcx > > ,
61+ type_cache : FxHashMap < Ty < ' tcx > , bool > ,
6162}
6263
6364impl < ' tcx > SignificantDropTightening < ' tcx > {
@@ -118,7 +119,7 @@ impl<'tcx> SignificantDropTightening<'tcx> {
118119 stmt : & hir:: Stmt < ' _ > ,
119120 cb : impl Fn ( & mut SigDropAuxParams ) ,
120121 ) {
121- let mut sig_drop_finder = SigDropFinder :: new ( cx, & mut self . seen_types ) ;
122+ let mut sig_drop_finder = SigDropFinder :: new ( cx, & mut self . seen_types , & mut self . type_cache ) ;
122123 sig_drop_finder. visit_expr ( expr) ;
123124 if sig_drop_finder. has_sig_drop {
124125 cb ( sdap) ;
@@ -296,15 +297,24 @@ impl Default for SigDropAuxParams {
296297struct SigDropChecker < ' cx , ' sdt , ' tcx > {
297298 cx : & ' cx LateContext < ' tcx > ,
298299 seen_types : & ' sdt mut FxHashSet < Ty < ' tcx > > ,
300+ type_cache : & ' sdt mut FxHashMap < Ty < ' tcx > , bool > ,
299301}
300302
301303impl < ' cx , ' sdt , ' tcx > SigDropChecker < ' cx , ' sdt , ' tcx > {
302- pub ( crate ) fn new ( cx : & ' cx LateContext < ' tcx > , seen_types : & ' sdt mut FxHashSet < Ty < ' tcx > > ) -> Self {
304+ pub ( crate ) fn new (
305+ cx : & ' cx LateContext < ' tcx > ,
306+ seen_types : & ' sdt mut FxHashSet < Ty < ' tcx > > ,
307+ type_cache : & ' sdt mut FxHashMap < Ty < ' tcx > , bool > ,
308+ ) -> Self {
303309 seen_types. clear ( ) ;
304- Self { cx, seen_types }
310+ Self {
311+ cx,
312+ seen_types,
313+ type_cache,
314+ }
305315 }
306316
307- pub ( crate ) fn has_sig_drop_attr ( & mut self , ty : Ty < ' tcx > ) -> bool {
317+ pub ( crate ) fn has_sig_drop_attr_uncached ( & mut self , ty : Ty < ' tcx > ) -> bool {
308318 if let Some ( adt) = ty. ty_adt_def ( ) {
309319 let mut iter = get_attr (
310320 self . cx . sess ( ) ,
@@ -340,6 +350,16 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> {
340350 }
341351 }
342352
353+ pub ( crate ) fn has_sig_drop_attr ( & mut self , ty : Ty < ' tcx > ) -> bool {
354+ // The borrow checker prevents us from using something fancier like or_insert_with.
355+ if let Some ( ty) = self . type_cache . get ( & ty) {
356+ return * ty;
357+ }
358+ let value = self . has_sig_drop_attr_uncached ( ty) ;
359+ self . type_cache . insert ( ty, value) ;
360+ value
361+ }
362+
343363 fn has_seen_ty ( & mut self , ty : Ty < ' tcx > ) -> bool {
344364 !self . seen_types . insert ( ty)
345365 }
@@ -353,11 +373,15 @@ struct SigDropFinder<'cx, 'sdt, 'tcx> {
353373}
354374
355375impl < ' cx , ' sdt , ' tcx > SigDropFinder < ' cx , ' sdt , ' tcx > {
356- fn new ( cx : & ' cx LateContext < ' tcx > , seen_types : & ' sdt mut FxHashSet < Ty < ' tcx > > ) -> Self {
376+ fn new (
377+ cx : & ' cx LateContext < ' tcx > ,
378+ seen_types : & ' sdt mut FxHashSet < Ty < ' tcx > > ,
379+ type_cache : & ' sdt mut FxHashMap < Ty < ' tcx > , bool > ,
380+ ) -> Self {
357381 Self {
358382 cx,
359383 has_sig_drop : false ,
360- sig_drop_checker : SigDropChecker :: new ( cx, seen_types) ,
384+ sig_drop_checker : SigDropChecker :: new ( cx, seen_types, type_cache ) ,
361385 }
362386 }
363387}
0 commit comments