@@ -4,8 +4,9 @@ use rustc_type_ir::data_structures::{HashMap, ensure_sufficient_stack};
4
4
use rustc_type_ir:: inherent:: * ;
5
5
use rustc_type_ir:: solve:: { Goal , QueryInput } ;
6
6
use 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 ,
9
10
} ;
10
11
11
12
use crate :: delegate:: SolverDelegate ;
@@ -109,20 +110,58 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
109
110
return ( param_env, Default :: default ( ) , Vec :: new ( ) ) ;
110
111
}
111
112
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 } ,
115
153
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 ,
120
158
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
+ }
126
165
}
127
166
128
167
/// When canonicalizing query inputs, we keep `'static` in the `param_env`
0 commit comments