@@ -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,51 @@ 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
+ let ty:: Infer ( ty:: TyVar ( vid) ) = v. expect_ty ( ) . kind ( ) else {
375
+ unreachable ! ( "expected `sub_root` to be an inference variable" ) ;
376
+ } ;
377
+ let ty:: Infer ( ty:: TyVar ( sub_root) ) = prev. expect_ty ( ) . kind ( ) else {
378
+ unreachable ! ( "expected `sub_root` to be an inference variable" ) ;
379
+ } ;
380
+ delegate. sub_ty_vids_raw ( vid, sub_root) ;
381
+ }
378
382
}
383
+ v
379
384
} 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 ( ) ]
385
+ // All new inference variables we create start out in the current universe
386
+ // of the caller. This is conceptually wrong as these inference variables
387
+ // would be able to name more placeholders then they should be able to.
388
+ // However the inference variables have to "come from somewhere", so by
389
+ // equating them with the original values of the caller later on, we pull
390
+ // them down into their correct universe again.
391
+ delegate. instantiate_canonical_var_with_infer ( info, span, & var_values, |_| {
392
+ prev_universe
393
+ } )
383
394
}
384
- } ) ,
385
- ) ;
386
-
387
- CanonicalVarValues { var_values }
395
+ } else {
396
+ // For placeholders which were already part of the input, we simply map this
397
+ // universal bound variable back the placeholder of the input.
398
+ original_values[ info. expect_placeholder_index ( ) ]
399
+ } ;
400
+ var_values. push ( value)
401
+ }
402
+ CanonicalVarValues { var_values : delegate. cx ( ) . mk_args ( & var_values) }
388
403
}
389
404
390
405
/// Unify the `original_values` with the `var_values` returned by the canonical query..
0 commit comments