1
- use crate :: FxHashSet ;
2
1
use clippy_utils:: {
3
2
diagnostics:: span_lint_and_then,
4
3
get_attr,
5
4
source:: { indent_of, snippet} ,
6
5
} ;
6
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
7
7
use rustc_errors:: { Applicability , Diagnostic } ;
8
8
use rustc_hir:: {
9
9
self as hir,
@@ -58,6 +58,7 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]);
58
58
pub struct SignificantDropTightening < ' tcx > {
59
59
/// Auxiliary structure used to avoid having to verify the same type multiple times.
60
60
seen_types : FxHashSet < Ty < ' tcx > > ,
61
+ type_cache : FxHashMap < Ty < ' tcx > , bool > ,
61
62
}
62
63
63
64
impl < ' tcx > SignificantDropTightening < ' tcx > {
@@ -118,7 +119,7 @@ impl<'tcx> SignificantDropTightening<'tcx> {
118
119
stmt : & hir:: Stmt < ' _ > ,
119
120
cb : impl Fn ( & mut SigDropAuxParams ) ,
120
121
) {
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 ) ;
122
123
sig_drop_finder. visit_expr ( expr) ;
123
124
if sig_drop_finder. has_sig_drop {
124
125
cb ( sdap) ;
@@ -296,15 +297,24 @@ impl Default for SigDropAuxParams {
296
297
struct SigDropChecker < ' cx , ' sdt , ' tcx > {
297
298
cx : & ' cx LateContext < ' tcx > ,
298
299
seen_types : & ' sdt mut FxHashSet < Ty < ' tcx > > ,
300
+ type_cache : & ' sdt mut FxHashMap < Ty < ' tcx > , bool > ,
299
301
}
300
302
301
303
impl < ' 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 {
303
309
seen_types. clear ( ) ;
304
- Self { cx, seen_types }
310
+ Self {
311
+ cx,
312
+ seen_types,
313
+ type_cache,
314
+ }
305
315
}
306
316
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 {
308
318
if let Some ( adt) = ty. ty_adt_def ( ) {
309
319
let mut iter = get_attr (
310
320
self . cx . sess ( ) ,
@@ -340,6 +350,16 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> {
340
350
}
341
351
}
342
352
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
+
343
363
fn has_seen_ty ( & mut self , ty : Ty < ' tcx > ) -> bool {
344
364
!self . seen_types . insert ( ty)
345
365
}
@@ -353,11 +373,15 @@ struct SigDropFinder<'cx, 'sdt, 'tcx> {
353
373
}
354
374
355
375
impl < ' 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 {
357
381
Self {
358
382
cx,
359
383
has_sig_drop : false ,
360
- sig_drop_checker : SigDropChecker :: new ( cx, seen_types) ,
384
+ sig_drop_checker : SigDropChecker :: new ( cx, seen_types, type_cache ) ,
361
385
}
362
386
}
363
387
}
0 commit comments