@@ -15,7 +15,8 @@ use rustc_index::IndexVec;
15
15
use rustc_type_ir:: inherent:: * ;
16
16
use rustc_type_ir:: relate:: solver_relating:: RelateExt ;
17
17
use rustc_type_ir:: {
18
- self as ty, Canonical , CanonicalVarValues , InferCtxtLike , Interner , TypeFoldable ,
18
+ self as ty, Canonical , CanonicalVarKind , CanonicalVarValues , InferCtxtLike , Interner ,
19
+ TypeFoldable ,
19
20
} ;
20
21
use tracing:: { debug, instrument, trace} ;
21
22
@@ -354,37 +355,55 @@ where
354
355
}
355
356
}
356
357
357
- let var_values = delegate. cx ( ) . mk_args_from_iter (
358
- response. variables . iter ( ) . enumerate ( ) . map ( |( index, info) | {
359
- if info. universe ( ) != ty:: UniverseIndex :: ROOT {
360
- // A variable from inside a binder of the query. While ideally these shouldn't
361
- // exist at all (see the FIXME at the start of this method), we have to deal with
362
- // them for now.
363
- delegate. instantiate_canonical_var_with_infer ( info, span, |idx| {
364
- prev_universe + idx. index ( )
365
- } )
366
- } else if info. is_existential ( ) {
367
- // As an optimization we sometimes avoid creating a new inference variable here.
368
- //
369
- // All new inference variables we create start out in the current universe of the caller.
370
- // This is conceptually wrong as these inference variables would be able to name
371
- // more placeholders then they should be able to. However the inference variables have
372
- // to "come from somewhere", so by equating them with the original values of the caller
373
- // later on, we pull them down into their correct universe again.
374
- if let Some ( v) = opt_values[ ty:: BoundVar :: from_usize ( index) ] {
375
- v
376
- } else {
377
- delegate. instantiate_canonical_var_with_infer ( info, span, |_| prev_universe)
358
+ let mut var_values = Vec :: new ( ) ;
359
+ for ( index, info) in response. variables . iter ( ) . enumerate ( ) {
360
+ let value = if info. universe ( ) != ty:: UniverseIndex :: ROOT {
361
+ // A variable from inside a binder of the query. While ideally these shouldn't
362
+ // exist at all (see the FIXME at the start of this method), we have to deal with
363
+ // them for now.
364
+ delegate. instantiate_canonical_var_with_infer ( info, span, & var_values, |idx| {
365
+ prev_universe + idx. index ( )
366
+ } )
367
+ } else if info. is_existential ( ) {
368
+ // As an optimization we sometimes avoid creating a new inference variable here.
369
+ // We need to still make sure to register any subtype relations returned by the
370
+ // query.
371
+ if let Some ( v) = opt_values[ ty:: BoundVar :: from_usize ( index) ] {
372
+ if let CanonicalVarKind :: Ty { universe : _, sub_root } = info. kind {
373
+ if let Some ( prev) = var_values. get ( sub_root. as_usize ( ) ) {
374
+ // We cannot simply assume that previous `var_values`
375
+ // are inference variables, see the comment in
376
+ // `instantiate_canonical_var`.
377
+ let v = delegate. shallow_resolve ( v. expect_ty ( ) ) ;
378
+ let prev = delegate. shallow_resolve ( prev. expect_ty ( ) ) ;
379
+ match ( v. kind ( ) , prev. kind ( ) ) {
380
+ ( ty:: Infer ( ty:: TyVar ( vid) ) , ty:: Infer ( ty:: TyVar ( sub_root) ) ) => {
381
+ delegate. sub_ty_vids_raw ( vid, sub_root)
382
+ }
383
+ _ => { }
384
+ }
385
+ }
378
386
}
387
+ v
379
388
} else {
380
- // For placeholders which were already part of the input, we simply map this
381
- // universal bound variable back the placeholder of the input.
382
- original_values[ info. expect_placeholder_index ( ) ]
389
+ // All new inference variables we create start out in the current universe
390
+ // of the caller. This is conceptually wrong as these inference variables
391
+ // would be able to name more placeholders then they should be able to.
392
+ // However the inference variables have to "come from somewhere", so by
393
+ // equating them with the original values of the caller later on, we pull
394
+ // them down into their correct universe again.
395
+ delegate. instantiate_canonical_var_with_infer ( info, span, & var_values, |_| {
396
+ prev_universe
397
+ } )
383
398
}
384
- } ) ,
385
- ) ;
386
-
387
- CanonicalVarValues { var_values }
399
+ } else {
400
+ // For placeholders which were already part of the input, we simply map this
401
+ // universal bound variable back the placeholder of the input.
402
+ original_values[ info. expect_placeholder_index ( ) ]
403
+ } ;
404
+ var_values. push ( value)
405
+ }
406
+ CanonicalVarValues { var_values : delegate. cx ( ) . mk_args ( & var_values) }
388
407
}
389
408
390
409
/// Unify the `original_values` with the `var_values` returned by the canonical query..
0 commit comments