@@ -15,7 +15,8 @@ use rustc_index::IndexVec;
1515use rustc_type_ir:: inherent:: * ;
1616use rustc_type_ir:: relate:: solver_relating:: RelateExt ;
1717use rustc_type_ir:: {
18- self as ty, Canonical , CanonicalVarValues , InferCtxtLike , Interner , TypeFoldable ,
18+ self as ty, Canonical , CanonicalVarKind , CanonicalVarValues , InferCtxtLike , Interner ,
19+ TypeFoldable ,
1920} ;
2021use tracing:: { debug, instrument, trace} ;
2122
@@ -344,37 +345,51 @@ where
344345 }
345346 }
346347
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+ }
368372 }
373+ v
369374 } 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+ } )
373384 }
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) }
378393 }
379394
380395 /// Unify the `original_values` with the `var_values` returned by the canonical query..
0 commit comments