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