@@ -4,8 +4,9 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
44use rustc_type_ir:: inherent:: * ;
55use rustc_type_ir:: solve:: { Goal , QueryInput } ;
66use rustc_type_ir:: {
7- self as ty, Canonical , CanonicalTyVarKind , CanonicalVarKind , Flags , InferCtxtLike , Interner ,
8- TypeFlags , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
7+ self as ty, Canonical , CanonicalParamEnvCacheEntry , CanonicalTyVarKind , CanonicalVarKind ,
8+ Flags , InferCtxtLike , Interner , TypeFlags , TypeFoldable , TypeFolder , TypeSuperFoldable ,
9+ TypeVisitableExt ,
910} ;
1011
1112use crate :: delegate:: SolverDelegate ;
@@ -109,20 +110,58 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
109110 return ( param_env, Default :: default ( ) , Vec :: new ( ) ) ;
110111 }
111112
112- let mut env_canonicalizer = Canonicalizer {
113- delegate,
114- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
113+ if !param_env. has_non_region_infer ( ) {
114+ delegate. cx ( ) . canonical_param_env_cache_get_or_insert (
115+ param_env,
116+ || {
117+ let mut variables = Vec :: new ( ) ;
118+ let mut env_canonicalizer = Canonicalizer {
119+ delegate,
120+ canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
121+
122+ variables : & mut variables,
123+ variable_lookup_table : Default :: default ( ) ,
124+ var_kinds : Vec :: new ( ) ,
125+ binder_index : ty:: INNERMOST ,
126+
127+ cache : Default :: default ( ) ,
128+ } ;
129+ let param_env = param_env. fold_with ( & mut env_canonicalizer) ;
130+ debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
131+ CanonicalParamEnvCacheEntry {
132+ param_env,
133+ variable_lookup_table : env_canonicalizer. variable_lookup_table ,
134+ var_kinds : env_canonicalizer. var_kinds ,
135+ variables,
136+ }
137+ } ,
138+ |& CanonicalParamEnvCacheEntry {
139+ param_env,
140+ variables : ref cache_variables,
141+ ref variable_lookup_table,
142+ ref var_kinds,
143+ } | {
144+ debug_assert ! ( variables. is_empty( ) ) ;
145+ variables. extend ( cache_variables. iter ( ) . copied ( ) ) ;
146+ ( param_env, variable_lookup_table. clone ( ) , var_kinds. clone ( ) )
147+ } ,
148+ )
149+ } else {
150+ let mut env_canonicalizer = Canonicalizer {
151+ delegate,
152+ canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
115153
116- variables,
117- variable_lookup_table : Default :: default ( ) ,
118- var_kinds : Vec :: new ( ) ,
119- binder_index : ty:: INNERMOST ,
154+ variables,
155+ variable_lookup_table : Default :: default ( ) ,
156+ var_kinds : Vec :: new ( ) ,
157+ binder_index : ty:: INNERMOST ,
120158
121- cache : Default :: default ( ) ,
122- } ;
123- let param_env = param_env. fold_with ( & mut env_canonicalizer) ;
124- debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
125- ( param_env, env_canonicalizer. variable_lookup_table , env_canonicalizer. var_kinds )
159+ cache : Default :: default ( ) ,
160+ } ;
161+ let param_env = param_env. fold_with ( & mut env_canonicalizer) ;
162+ debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
163+ ( param_env, env_canonicalizer. variable_lookup_table , env_canonicalizer. var_kinds )
164+ }
126165 }
127166
128167 /// When canonicalizing query inputs, we keep `'static` in the `param_env`
0 commit comments