@@ -4,8 +4,8 @@ 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 , InferCtxtLike , Interner ,
8
- TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
7
+ self as ty, Canonical , CanonicalParamEnvCacheEntry , CanonicalTyVarKind , CanonicalVarKind ,
8
+ InferCtxtLike , Interner , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
9
9
} ;
10
10
11
11
use crate :: delegate:: SolverDelegate ;
@@ -91,20 +91,58 @@ impl<'a, D: SolverDelegate<Interner = I>, I: Interner> Canonicalizer<'a, D, I> {
91
91
variables : & ' a mut Vec < I :: GenericArg > ,
92
92
param_env : I :: ParamEnv ,
93
93
) -> ( 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 } ,
97
134
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 ,
102
139
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
+ }
108
146
}
109
147
110
148
/// When canonicalizing query inputs, we keep `'static` in the `param_env`
0 commit comments