@@ -13,6 +13,7 @@ use std::iter;
13
13
use rustc_index:: { Idx , IndexVec } ;
14
14
use rustc_middle:: arena:: ArenaAllocatable ;
15
15
use rustc_middle:: bug;
16
+ use rustc_middle:: infer:: canonical:: CanonicalVarKind ;
16
17
use rustc_middle:: ty:: { self , BoundVar , GenericArg , GenericArgKind , Ty , TyCtxt , TypeFoldable } ;
17
18
use tracing:: { debug, instrument} ;
18
19
@@ -413,35 +414,34 @@ impl<'tcx> InferCtxt<'tcx> {
413
414
let mut opt_values: IndexVec < BoundVar , Option < GenericArg < ' tcx > > > =
414
415
IndexVec :: from_elem_n ( None , query_response. variables . len ( ) ) ;
415
416
416
- // In terms of our example above, we are iterating over pairs like:
417
- // [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
418
417
for ( original_value, result_value) in iter:: zip ( & original_values. var_values , result_values)
419
418
{
420
419
match result_value. kind ( ) {
421
420
GenericArgKind :: Type ( result_value) => {
422
- // e.g., here `result_value` might be `?0` in the example above...
423
- if let ty:: Bound ( debruijn, b) = * result_value. kind ( ) {
424
- // ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
425
-
421
+ // We disable the instantiation guess for inference variables
422
+ // and only use it for placeholders. We need to handle the
423
+ // `sub_root` of type inference variables which would make this
424
+ // more involved. They are also a lot rarer than region variables.
425
+ if let ty:: Bound ( debruijn, b) = * result_value. kind ( )
426
+ && !matches ! (
427
+ query_response. variables[ b. var. as_usize( ) ] ,
428
+ CanonicalVarKind :: Ty { .. }
429
+ )
430
+ {
426
431
// We only allow a `ty::INNERMOST` index in generic parameters.
427
432
assert_eq ! ( debruijn, ty:: INNERMOST ) ;
428
433
opt_values[ b. var ] = Some ( * original_value) ;
429
434
}
430
435
}
431
436
GenericArgKind :: Lifetime ( result_value) => {
432
- // e.g., here `result_value` might be `'?1` in the example above...
433
437
if let ty:: ReBound ( debruijn, b) = result_value. kind ( ) {
434
- // ... in which case we would set `canonical_vars[0]` to `Some('static)`.
435
-
436
438
// We only allow a `ty::INNERMOST` index in generic parameters.
437
439
assert_eq ! ( debruijn, ty:: INNERMOST ) ;
438
440
opt_values[ b. var ] = Some ( * original_value) ;
439
441
}
440
442
}
441
443
GenericArgKind :: Const ( result_value) => {
442
444
if let ty:: ConstKind :: Bound ( debruijn, b) = result_value. kind ( ) {
443
- // ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
444
-
445
445
// We only allow a `ty::INNERMOST` index in generic parameters.
446
446
assert_eq ! ( debruijn, ty:: INNERMOST ) ;
447
447
opt_values[ b. var ] = Some ( * original_value) ;
@@ -453,39 +453,36 @@ impl<'tcx> InferCtxt<'tcx> {
453
453
// Create result arguments: if we found a value for a
454
454
// given variable in the loop above, use that. Otherwise, use
455
455
// a fresh inference variable.
456
- let result_args = CanonicalVarValues {
457
- var_values : self . tcx . mk_args_from_iter (
458
- query_response. variables . iter ( ) . enumerate ( ) . map ( |( index, var_kind) | {
459
- if var_kind. universe ( ) != ty:: UniverseIndex :: ROOT {
460
- // A variable from inside a binder of the query. While ideally these shouldn't
461
- // exist at all, we have to deal with them for now.
462
- self . instantiate_canonical_var ( cause. span , var_kind, |u| {
463
- universe_map[ u. as_usize ( ) ]
464
- } )
465
- } else if var_kind. is_existential ( ) {
466
- match opt_values[ BoundVar :: new ( index) ] {
467
- Some ( k) => k,
468
- None => self . instantiate_canonical_var ( cause. span , var_kind, |u| {
469
- universe_map[ u. as_usize ( ) ]
470
- } ) ,
471
- }
472
- } else {
473
- // For placeholders which were already part of the input, we simply map this
474
- // universal bound variable back the placeholder of the input.
475
- opt_values[ BoundVar :: new ( index) ] . expect (
476
- "expected placeholder to be unified with itself during response" ,
477
- )
478
- }
479
- } ) ,
480
- ) ,
481
- } ;
456
+ let tcx = self . tcx ;
457
+ let variables = query_response. variables ;
458
+ let var_values = CanonicalVarValues :: instantiate ( tcx, variables, |var_values, kind| {
459
+ if kind. universe ( ) != ty:: UniverseIndex :: ROOT {
460
+ // A variable from inside a binder of the query. While ideally these shouldn't
461
+ // exist at all, we have to deal with them for now.
462
+ self . instantiate_canonical_var ( cause. span , kind, & var_values, |u| {
463
+ universe_map[ u. as_usize ( ) ]
464
+ } )
465
+ } else if kind. is_existential ( ) {
466
+ match opt_values[ BoundVar :: new ( var_values. len ( ) ) ] {
467
+ Some ( k) => k,
468
+ None => self . instantiate_canonical_var ( cause. span , kind, & var_values, |u| {
469
+ universe_map[ u. as_usize ( ) ]
470
+ } ) ,
471
+ }
472
+ } else {
473
+ // For placeholders which were already part of the input, we simply map this
474
+ // universal bound variable back the placeholder of the input.
475
+ opt_values[ BoundVar :: new ( var_values. len ( ) ) ]
476
+ . expect ( "expected placeholder to be unified with itself during response" )
477
+ }
478
+ } ) ;
482
479
483
480
let mut obligations = PredicateObligations :: new ( ) ;
484
481
485
482
// Carry all newly resolved opaque types to the caller's scope
486
483
for & ( a, b) in & query_response. value . opaque_types {
487
- let a = instantiate_value ( self . tcx , & result_args , a) ;
488
- let b = instantiate_value ( self . tcx , & result_args , b) ;
484
+ let a = instantiate_value ( self . tcx , & var_values , a) ;
485
+ let b = instantiate_value ( self . tcx , & var_values , b) ;
489
486
debug ! ( ?a, ?b, "constrain opaque type" ) ;
490
487
// We use equate here instead of, for example, just registering the
491
488
// opaque type's hidden value directly, because the hidden type may have been an inference
@@ -502,7 +499,7 @@ impl<'tcx> InferCtxt<'tcx> {
502
499
) ;
503
500
}
504
501
505
- Ok ( InferOk { value : result_args , obligations } )
502
+ Ok ( InferOk { value : var_values , obligations } )
506
503
}
507
504
508
505
/// Given a "guess" at the values for the canonical variables in
0 commit comments