@@ -5,6 +5,7 @@ use crate::ty::{
55 self , EarlyBinder , GenericArgs , GenericArgsRef , Ty , TyCtxt , TypeFoldable , TypeSuperFoldable ,
66 TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor ,
77} ;
8+ use rustc_data_structures:: fx:: FxHashMap ;
89use rustc_errors:: ErrorGuaranteed ;
910use rustc_hir as hir;
1011use rustc_hir:: def:: Namespace ;
@@ -388,21 +389,33 @@ impl<'tcx> InstanceKind<'tcx> {
388389}
389390
390391fn type_length < ' tcx > ( item : impl TypeVisitable < TyCtxt < ' tcx > > ) -> usize {
391- struct Visitor {
392+ struct Visitor < ' tcx > {
392393 type_length : usize ,
394+ cache : FxHashMap < Ty < ' tcx > , usize > ,
393395 }
394- impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for Visitor {
396+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for Visitor < ' tcx > {
395397 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 ;
396404 self . type_length += 1 ;
397405 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+ }
398411 }
399412
400413 fn visit_const ( & mut self , ct : ty:: Const < ' tcx > ) {
401414 self . type_length += 1 ;
402415 ct. super_visit_with ( self ) ;
403416 }
404417 }
405- let mut visitor = Visitor { type_length : 0 } ;
418+ let mut visitor = Visitor { type_length : 0 , cache : Default :: default ( ) } ;
406419 item. visit_with ( & mut visitor) ;
407420
408421 visitor. type_length
0 commit comments