@@ -4,8 +4,8 @@ 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 , InferCtxtLike , Interner ,
8- TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
7+ self as ty, Canonical , CanonicalParamEnvCacheEntry , CanonicalTyVarKind , CanonicalVarKind ,
8+ InferCtxtLike , Interner , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
99} ;
1010
1111use crate :: delegate:: SolverDelegate ;
@@ -91,20 +91,58 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
9191 variables : & ' a mut Vec < I :: GenericArg > ,
9292 param_env : I :: ParamEnv ,
9393 ) -> ( I :: ParamEnv , HashMap < I :: GenericArg , usize > , Vec < CanonicalVarKind < I > > ) {
94- let mut env_canonicalizer = Canonicalizer {
95- delegate,
96- canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
94+ if !param_env. has_non_region_infer ( ) {
95+ delegate. cx ( ) . canonical_param_env_cache_get_or_insert (
96+ param_env,
97+ || {
98+ let mut variables = Vec :: new ( ) ;
99+ let mut env_canonicalizer = Canonicalizer {
100+ delegate,
101+ canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
102+
103+ variables : & mut variables,
104+ variable_lookup_table : Default :: default ( ) ,
105+ var_kinds : Vec :: new ( ) ,
106+ binder_index : ty:: INNERMOST ,
107+
108+ cache : Default :: default ( ) ,
109+ } ;
110+ let param_env = param_env. fold_with ( & mut env_canonicalizer) ;
111+ debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
112+ CanonicalParamEnvCacheEntry {
113+ param_env,
114+ variable_lookup_table : env_canonicalizer. variable_lookup_table ,
115+ var_kinds : env_canonicalizer. var_kinds ,
116+ variables,
117+ }
118+ } ,
119+ |& CanonicalParamEnvCacheEntry {
120+ param_env,
121+ variables : ref cache_variables,
122+ ref variable_lookup_table,
123+ ref var_kinds,
124+ } | {
125+ debug_assert ! ( variables. is_empty( ) ) ;
126+ variables. extend ( cache_variables. iter ( ) . copied ( ) ) ;
127+ ( param_env, variable_lookup_table. clone ( ) , var_kinds. clone ( ) )
128+ } ,
129+ )
130+ } else {
131+ let mut env_canonicalizer = Canonicalizer {
132+ delegate,
133+ canonicalize_mode : CanonicalizeMode :: Input { keep_static : true } ,
97134
98- variables,
99- variable_lookup_table : Default :: default ( ) ,
100- var_kinds : Vec :: new ( ) ,
101- binder_index : ty:: INNERMOST ,
135+ variables,
136+ variable_lookup_table : Default :: default ( ) ,
137+ var_kinds : Vec :: new ( ) ,
138+ binder_index : ty:: INNERMOST ,
102139
103- cache : Default :: default ( ) ,
104- } ;
105- let param_env = param_env. fold_with ( & mut env_canonicalizer) ;
106- debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
107- ( param_env, env_canonicalizer. variable_lookup_table , env_canonicalizer. var_kinds )
140+ cache : Default :: default ( ) ,
141+ } ;
142+ let param_env = param_env. fold_with ( & mut env_canonicalizer) ;
143+ debug_assert_eq ! ( env_canonicalizer. binder_index, ty:: INNERMOST ) ;
144+ ( param_env, env_canonicalizer. variable_lookup_table , env_canonicalizer. var_kinds )
145+ }
108146 }
109147
110148 /// When canonicalizing query inputs, we keep `'static` in the `param_env`
0 commit comments