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