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