@@ -5,6 +5,7 @@ use crate::ty::{
5
5
self , EarlyBinder , GenericArgs , GenericArgsRef , Ty , TyCtxt , TypeFoldable , TypeSuperFoldable ,
6
6
TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor ,
7
7
} ;
8
+ use rustc_data_structures:: fx:: FxHashMap ;
8
9
use rustc_errors:: ErrorGuaranteed ;
9
10
use rustc_hir as hir;
10
11
use rustc_hir:: def:: Namespace ;
@@ -388,21 +389,33 @@ impl<'tcx> InstanceKind<'tcx> {
388
389
}
389
390
390
391
fn type_length < ' tcx > ( item : impl TypeVisitable < TyCtxt < ' tcx > > ) -> usize {
391
- struct Visitor {
392
+ struct Visitor < ' tcx > {
392
393
type_length : usize ,
394
+ cache : FxHashMap < Ty < ' tcx > , usize > ,
393
395
}
394
- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for Visitor {
396
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for Visitor < ' tcx > {
395
397
fn visit_ty ( & mut self , t : Ty < ' tcx > ) {
398
+ if let Some ( & value) = self . cache . get ( & t) {
399
+ self . type_length += value;
400
+ return ;
401
+ }
402
+
403
+ let prev = self . type_length ;
396
404
self . type_length += 1 ;
397
405
t. super_visit_with ( self ) ;
406
+
407
+ // We don't try to use the cache if the type is fairly small.
408
+ if self . type_length > 16 {
409
+ self . cache . insert ( t, self . type_length - prev) ;
410
+ }
398
411
}
399
412
400
413
fn visit_const ( & mut self , ct : ty:: Const < ' tcx > ) {
401
414
self . type_length += 1 ;
402
415
ct. super_visit_with ( self ) ;
403
416
}
404
417
}
405
- let mut visitor = Visitor { type_length : 0 } ;
418
+ let mut visitor = Visitor { type_length : 0 , cache : Default :: default ( ) } ;
406
419
item. visit_with ( & mut visitor) ;
407
420
408
421
visitor. type_length
0 commit comments