@@ -13,6 +13,7 @@ use std::iter;
1313use rustc_index:: { Idx , IndexVec } ;
1414use rustc_middle:: arena:: ArenaAllocatable ;
1515use rustc_middle:: bug;
16+ use rustc_middle:: infer:: canonical:: CanonicalVarKind ;
1617use rustc_middle:: ty:: { self , BoundVar , GenericArg , GenericArgKind , Ty , TyCtxt , TypeFoldable } ;
1718use tracing:: { debug, instrument} ;
1819
@@ -413,35 +414,34 @@ impl<'tcx> InferCtxt<'tcx> {
413414 let mut opt_values: IndexVec < BoundVar , Option < GenericArg < ' tcx > > > =
414415 IndexVec :: from_elem_n ( None , query_response. variables . len ( ) ) ;
415416
416- // In terms of our example above, we are iterating over pairs like:
417- // [(?A, Vec<?0>), ('static, '?1), (?B, ?0)]
418417 for ( original_value, result_value) in iter:: zip ( & original_values. var_values , result_values)
419418 {
420419 match result_value. kind ( ) {
421420 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+ {
426431 // We only allow a `ty::INNERMOST` index in generic parameters.
427432 assert_eq ! ( debruijn, ty:: INNERMOST ) ;
428433 opt_values[ b. var ] = Some ( * original_value) ;
429434 }
430435 }
431436 GenericArgKind :: Lifetime ( result_value) => {
432- // e.g., here `result_value` might be `'?1` in the example above...
433437 if let ty:: ReBound ( debruijn, b) = result_value. kind ( ) {
434- // ... in which case we would set `canonical_vars[0]` to `Some('static)`.
435-
436438 // We only allow a `ty::INNERMOST` index in generic parameters.
437439 assert_eq ! ( debruijn, ty:: INNERMOST ) ;
438440 opt_values[ b. var ] = Some ( * original_value) ;
439441 }
440442 }
441443 GenericArgKind :: Const ( result_value) => {
442444 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-
445445 // We only allow a `ty::INNERMOST` index in generic parameters.
446446 assert_eq ! ( debruijn, ty:: INNERMOST ) ;
447447 opt_values[ b. var ] = Some ( * original_value) ;
@@ -453,39 +453,36 @@ impl<'tcx> InferCtxt<'tcx> {
453453 // Create result arguments: if we found a value for a
454454 // given variable in the loop above, use that. Otherwise, use
455455 // 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+ } ) ;
482479
483480 let mut obligations = PredicateObligations :: new ( ) ;
484481
485482 // Carry all newly resolved opaque types to the caller's scope
486483 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) ;
489486 debug ! ( ?a, ?b, "constrain opaque type" ) ;
490487 // We use equate here instead of, for example, just registering the
491488 // opaque type's hidden value directly, because the hidden type may have been an inference
@@ -502,7 +499,7 @@ impl<'tcx> InferCtxt<'tcx> {
502499 ) ;
503500 }
504501
505- Ok ( InferOk { value : result_args , obligations } )
502+ Ok ( InferOk { value : var_values , obligations } )
506503 }
507504
508505 /// Given a "guess" at the values for the canonical variables in
0 commit comments