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