@@ -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
@@ -420,7 +421,12 @@ impl<'tcx> InferCtxt<'tcx> {
420421 match result_value. kind ( ) {
421422 GenericArgKind :: Type ( result_value) => {
422423 // e.g., here `result_value` might be `?0` in the example above...
423- if let ty:: Bound ( debruijn, b) = * result_value. kind ( ) {
424+ if let ty:: Bound ( debruijn, b) = * result_value. kind ( )
425+ && !matches ! (
426+ query_response. variables[ b. var. as_usize( ) ] ,
427+ CanonicalVarKind :: Ty { .. }
428+ )
429+ {
424430 // ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
425431
426432 // We only allow a `ty::INNERMOST` index in generic parameters.
@@ -453,39 +459,36 @@ impl<'tcx> InferCtxt<'tcx> {
453459 // Create result arguments: if we found a value for a
454460 // given variable in the loop above, use that. Otherwise, use
455461 // 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- } ;
462+ let tcx = self . tcx ;
463+ let variables = query_response. variables ;
464+ let var_values = CanonicalVarValues :: instantiate ( tcx, variables, |var_values, kind| {
465+ if kind. universe ( ) != ty:: UniverseIndex :: ROOT {
466+ // A variable from inside a binder of the query. While ideally these shouldn't
467+ // exist at all, we have to deal with them for now.
468+ self . instantiate_canonical_var ( cause. span , kind, & var_values, |u| {
469+ universe_map[ u. as_usize ( ) ]
470+ } )
471+ } else if kind. is_existential ( ) {
472+ match opt_values[ BoundVar :: new ( var_values. len ( ) ) ] {
473+ Some ( k) => k,
474+ None => self . instantiate_canonical_var ( cause. span , kind, & var_values, |u| {
475+ universe_map[ u. as_usize ( ) ]
476+ } ) ,
477+ }
478+ } else {
479+ // For placeholders which were already part of the input, we simply map this
480+ // universal bound variable back the placeholder of the input.
481+ opt_values[ BoundVar :: new ( var_values. len ( ) ) ]
482+ . expect ( "expected placeholder to be unified with itself during response" )
483+ }
484+ } ) ;
482485
483486 let mut obligations = PredicateObligations :: new ( ) ;
484487
485488 // Carry all newly resolved opaque types to the caller's scope
486489 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) ;
490+ let a = instantiate_value ( self . tcx , & var_values , a) ;
491+ let b = instantiate_value ( self . tcx , & var_values , b) ;
489492 debug ! ( ?a, ?b, "constrain opaque type" ) ;
490493 // We use equate here instead of, for example, just registering the
491494 // opaque type's hidden value directly, because the hidden type may have been an inference
@@ -502,7 +505,7 @@ impl<'tcx> InferCtxt<'tcx> {
502505 ) ;
503506 }
504507
505- Ok ( InferOk { value : result_args , obligations } )
508+ Ok ( InferOk { value : var_values , obligations } )
506509 }
507510
508511 /// Given a "guess" at the values for the canonical variables in
0 commit comments