@@ -20,6 +20,7 @@ use rustc_middle::ty::{
20
20
CoercePredicate , RegionOutlivesPredicate , SubtypePredicate , TypeOutlivesPredicate ,
21
21
} ;
22
22
23
+ mod alias_relate;
23
24
mod assembly;
24
25
mod canonicalize;
25
26
mod eval_ctxt;
@@ -154,142 +155,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
154
155
}
155
156
}
156
157
157
- #[ instrument( level = "debug" , skip( self ) , ret) ]
158
- fn compute_alias_relate_goal (
159
- & mut self ,
160
- goal : Goal < ' tcx , ( ty:: Term < ' tcx > , ty:: Term < ' tcx > , ty:: AliasRelationDirection ) > ,
161
- ) -> QueryResult < ' tcx > {
162
- let tcx = self . tcx ( ) ;
163
- // We may need to invert the alias relation direction if dealing an alias on the RHS.
164
- #[ derive( Debug ) ]
165
- enum Invert {
166
- No ,
167
- Yes ,
168
- }
169
- let evaluate_normalizes_to =
170
- |ecx : & mut EvalCtxt < ' _ , ' tcx > , alias, other, direction, invert| {
171
- let span = tracing:: span!(
172
- tracing:: Level :: DEBUG ,
173
- "compute_alias_relate_goal(evaluate_normalizes_to)" ,
174
- ?alias,
175
- ?other,
176
- ?direction,
177
- ?invert
178
- ) ;
179
- let _enter = span. enter ( ) ;
180
- let result = ecx. probe ( |ecx| {
181
- let other = match direction {
182
- // This is purely an optimization.
183
- ty:: AliasRelationDirection :: Equate => other,
184
-
185
- ty:: AliasRelationDirection :: Subtype => {
186
- let fresh = ecx. next_term_infer_of_kind ( other) ;
187
- let ( sub, sup) = match invert {
188
- Invert :: No => ( fresh, other) ,
189
- Invert :: Yes => ( other, fresh) ,
190
- } ;
191
- ecx. sub ( goal. param_env , sub, sup) ?;
192
- fresh
193
- }
194
- } ;
195
- ecx. add_goal ( goal. with (
196
- tcx,
197
- ty:: Binder :: dummy ( ty:: ProjectionPredicate {
198
- projection_ty : alias,
199
- term : other,
200
- } ) ,
201
- ) ) ;
202
- ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
203
- } ) ;
204
- debug ! ( ?result) ;
205
- result
206
- } ;
207
-
208
- let ( lhs, rhs, direction) = goal. predicate ;
209
-
210
- if lhs. is_infer ( ) || rhs. is_infer ( ) {
211
- bug ! (
212
- "`AliasRelate` goal with an infer var on lhs or rhs which should have been instantiated"
213
- ) ;
214
- }
215
-
216
- match ( lhs. to_alias_ty ( tcx) , rhs. to_alias_ty ( tcx) ) {
217
- ( None , None ) => bug ! ( "`AliasRelate` goal without an alias on either lhs or rhs" ) ,
218
-
219
- // RHS is not a projection, only way this is true is if LHS normalizes-to RHS
220
- ( Some ( alias_lhs) , None ) => {
221
- evaluate_normalizes_to ( self , alias_lhs, rhs, direction, Invert :: No )
222
- }
223
-
224
- // LHS is not a projection, only way this is true is if RHS normalizes-to LHS
225
- ( None , Some ( alias_rhs) ) => {
226
- evaluate_normalizes_to ( self , alias_rhs, lhs, direction, Invert :: Yes )
227
- }
228
-
229
- ( Some ( alias_lhs) , Some ( alias_rhs) ) => {
230
- debug ! ( "both sides are aliases" ) ;
231
-
232
- let mut candidates = Vec :: new ( ) ;
233
- // LHS normalizes-to RHS
234
- candidates. extend ( evaluate_normalizes_to (
235
- self ,
236
- alias_lhs,
237
- rhs,
238
- direction,
239
- Invert :: No ,
240
- ) ) ;
241
- // RHS normalizes-to RHS
242
- candidates. extend ( evaluate_normalizes_to (
243
- self ,
244
- alias_rhs,
245
- lhs,
246
- direction,
247
- Invert :: Yes ,
248
- ) ) ;
249
- // Relate via substs
250
- let subst_relate_response = self . probe ( |ecx| {
251
- let span = tracing:: span!(
252
- tracing:: Level :: DEBUG ,
253
- "compute_alias_relate_goal(relate_via_substs)" ,
254
- ?alias_lhs,
255
- ?alias_rhs,
256
- ?direction
257
- ) ;
258
- let _enter = span. enter ( ) ;
259
-
260
- match direction {
261
- ty:: AliasRelationDirection :: Equate => {
262
- ecx. eq ( goal. param_env , alias_lhs, alias_rhs) ?;
263
- }
264
- ty:: AliasRelationDirection :: Subtype => {
265
- ecx. sub ( goal. param_env , alias_lhs, alias_rhs) ?;
266
- }
267
- }
268
-
269
- ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
270
- } ) ;
271
- candidates. extend ( subst_relate_response) ;
272
- debug ! ( ?candidates) ;
273
-
274
- if let Some ( merged) = self . try_merge_responses ( & candidates) {
275
- Ok ( merged)
276
- } else {
277
- // When relating two aliases and we have ambiguity, we prefer
278
- // relating the generic arguments of the aliases over normalizing
279
- // them. This is necessary for inference during typeck.
280
- //
281
- // As this is incomplete, we must not do so during coherence.
282
- match ( self . solver_mode ( ) , subst_relate_response) {
283
- ( SolverMode :: Normal , Ok ( response) ) => Ok ( response) ,
284
- ( SolverMode :: Normal , Err ( NoSolution ) ) | ( SolverMode :: Coherence , _) => {
285
- self . flounder ( & candidates)
286
- }
287
- }
288
- }
289
- }
290
- }
291
- }
292
-
293
158
#[ instrument( level = "debug" , skip( self ) , ret) ]
294
159
fn compute_const_arg_has_type_goal (
295
160
& mut self ,
0 commit comments