@@ -17,8 +17,7 @@ use tracing::debug;
1717
1818use crate :: infer:: InferCtxt ;
1919use crate :: infer:: canonical:: {
20- Canonical , CanonicalQueryInput , CanonicalTyVarKind , CanonicalVarInfo , CanonicalVarKind ,
21- OriginalQueryValues ,
20+ Canonical , CanonicalQueryInput , CanonicalVarInfo , CanonicalVarKind , OriginalQueryValues ,
2221} ;
2322
2423impl < ' tcx > InferCtxt < ' tcx > {
@@ -299,6 +298,7 @@ struct Canonicalizer<'cx, 'tcx> {
299298 // Note that indices is only used once `var_values` is big enough to be
300299 // heap-allocated.
301300 indices : FxHashMap < GenericArg < ' tcx > , BoundVar > ,
301+ sub_root_lookup_table : FxHashMap < ty:: TyVid , usize > ,
302302 canonicalize_mode : & ' cx dyn CanonicalizeMode ,
303303 needs_canonical_flags : TypeFlags ,
304304
@@ -367,9 +367,10 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
367367 // FIXME: perf problem described in #55921.
368368 ui = ty:: UniverseIndex :: ROOT ;
369369 }
370+ let sub_root = self . get_or_insert_sub_root ( vid) ;
370371 self . canonicalize_ty_var (
371372 CanonicalVarInfo {
372- kind : CanonicalVarKind :: Ty ( CanonicalTyVarKind :: General ( ui ) ) ,
373+ kind : CanonicalVarKind :: Ty { universe : ui , sub_root } ,
373374 } ,
374375 t,
375376 )
@@ -382,21 +383,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
382383 if nt != t {
383384 return self . fold_ty ( nt) ;
384385 } else {
385- self . canonicalize_ty_var (
386- CanonicalVarInfo { kind : CanonicalVarKind :: Ty ( CanonicalTyVarKind :: Int ) } ,
387- t,
388- )
386+ self . canonicalize_ty_var ( CanonicalVarInfo { kind : CanonicalVarKind :: Int } , t)
389387 }
390388 }
391389 ty:: Infer ( ty:: FloatVar ( vid) ) => {
392390 let nt = self . infcx . unwrap ( ) . opportunistic_resolve_float_var ( vid) ;
393391 if nt != t {
394392 return self . fold_ty ( nt) ;
395393 } else {
396- self . canonicalize_ty_var (
397- CanonicalVarInfo { kind : CanonicalVarKind :: Ty ( CanonicalTyVarKind :: Float ) } ,
398- t,
399- )
394+ self . canonicalize_ty_var ( CanonicalVarInfo { kind : CanonicalVarKind :: Float } , t)
400395 }
401396 }
402397
@@ -576,6 +571,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
576571 variables : SmallVec :: from_slice ( base. variables ) ,
577572 query_state,
578573 indices : FxHashMap :: default ( ) ,
574+ sub_root_lookup_table : Default :: default ( ) ,
579575 binder_index : ty:: INNERMOST ,
580576 } ;
581577 if canonicalizer. query_state . var_values . spilled ( ) {
@@ -670,6 +666,13 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
670666 }
671667 }
672668
669+ fn get_or_insert_sub_root ( & mut self , vid : ty:: TyVid ) -> ty:: BoundVar {
670+ let root_vid = self . infcx . unwrap ( ) . sub_root_var ( vid) ;
671+ let idx =
672+ * self . sub_root_lookup_table . entry ( root_vid) . or_insert_with ( || self . variables . len ( ) ) ;
673+ ty:: BoundVar :: from ( idx)
674+ }
675+
673676 /// Replaces the universe indexes used in `var_values` with their index in
674677 /// `query_state.universe_map`. This minimizes the maximum universe used in
675678 /// the canonicalized value.
@@ -690,11 +693,11 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
690693 . iter ( )
691694 . map ( |v| CanonicalVarInfo {
692695 kind : match v. kind {
693- CanonicalVarKind :: Ty ( CanonicalTyVarKind :: Int | CanonicalTyVarKind :: Float ) => {
696+ CanonicalVarKind :: Int | CanonicalVarKind :: Float => {
694697 return * v;
695698 }
696- CanonicalVarKind :: Ty ( CanonicalTyVarKind :: General ( u ) ) => {
697- CanonicalVarKind :: Ty ( CanonicalTyVarKind :: General ( reverse_universe_map[ & u ] ) )
699+ CanonicalVarKind :: Ty { universe , sub_root } => {
700+ CanonicalVarKind :: Ty { universe : reverse_universe_map[ & universe ] , sub_root }
698701 }
699702 CanonicalVarKind :: Region ( u) => {
700703 CanonicalVarKind :: Region ( reverse_universe_map[ & u] )
0 commit comments