@@ -17,8 +17,7 @@ use tracing::debug;
17
17
18
18
use crate :: infer:: InferCtxt ;
19
19
use crate :: infer:: canonical:: {
20
- Canonical , CanonicalQueryInput , CanonicalTyVarKind , CanonicalVarInfo , CanonicalVarKind ,
21
- OriginalQueryValues ,
20
+ Canonical , CanonicalQueryInput , CanonicalVarInfo , CanonicalVarKind , OriginalQueryValues ,
22
21
} ;
23
22
24
23
impl < ' tcx > InferCtxt < ' tcx > {
@@ -299,6 +298,7 @@ struct Canonicalizer<'cx, 'tcx> {
299
298
// Note that indices is only used once `var_values` is big enough to be
300
299
// heap-allocated.
301
300
indices : FxHashMap < GenericArg < ' tcx > , BoundVar > ,
301
+ sub_root_lookup_table : FxHashMap < ty:: TyVid , usize > ,
302
302
canonicalize_mode : & ' cx dyn CanonicalizeMode ,
303
303
needs_canonical_flags : TypeFlags ,
304
304
@@ -367,9 +367,10 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
367
367
// FIXME: perf problem described in #55921.
368
368
ui = ty:: UniverseIndex :: ROOT ;
369
369
}
370
+ let sub_root = self . get_or_insert_sub_root ( vid) ;
370
371
self . canonicalize_ty_var (
371
372
CanonicalVarInfo {
372
- kind : CanonicalVarKind :: Ty ( CanonicalTyVarKind :: General ( ui ) ) ,
373
+ kind : CanonicalVarKind :: Ty { universe : ui , sub_root } ,
373
374
} ,
374
375
t,
375
376
)
@@ -382,21 +383,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
382
383
if nt != t {
383
384
return self . fold_ty ( nt) ;
384
385
} 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)
389
387
}
390
388
}
391
389
ty:: Infer ( ty:: FloatVar ( vid) ) => {
392
390
let nt = self . infcx . unwrap ( ) . opportunistic_resolve_float_var ( vid) ;
393
391
if nt != t {
394
392
return self . fold_ty ( nt) ;
395
393
} 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)
400
395
}
401
396
}
402
397
@@ -576,6 +571,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
576
571
variables : SmallVec :: from_slice ( base. variables ) ,
577
572
query_state,
578
573
indices : FxHashMap :: default ( ) ,
574
+ sub_root_lookup_table : Default :: default ( ) ,
579
575
binder_index : ty:: INNERMOST ,
580
576
} ;
581
577
if canonicalizer. query_state . var_values . spilled ( ) {
@@ -670,6 +666,13 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
670
666
}
671
667
}
672
668
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
+
673
676
/// Replaces the universe indexes used in `var_values` with their index in
674
677
/// `query_state.universe_map`. This minimizes the maximum universe used in
675
678
/// the canonicalized value.
@@ -690,11 +693,11 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
690
693
. iter ( )
691
694
. map ( |v| CanonicalVarInfo {
692
695
kind : match v. kind {
693
- CanonicalVarKind :: Ty ( CanonicalTyVarKind :: Int | CanonicalTyVarKind :: Float ) => {
696
+ CanonicalVarKind :: Int | CanonicalVarKind :: Float => {
694
697
return * v;
695
698
}
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 }
698
701
}
699
702
CanonicalVarKind :: Region ( u) => {
700
703
CanonicalVarKind :: Region ( reverse_universe_map[ & u] )
0 commit comments