@@ -35,6 +35,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
3535use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
3636use rustc_middle:: ty:: relate:: { RelateResult , TypeRelation } ;
3737use rustc_middle:: ty:: { self , InferConst , ToPredicate , Ty , TyCtxt , TypeVisitableExt } ;
38+ use rustc_middle:: ty:: { AliasRelationDirection , TyVar } ;
3839use rustc_middle:: ty:: { IntType , UintType } ;
3940use rustc_span:: DUMMY_SP ;
4041
@@ -459,7 +460,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
459460 ambient_variance,
460461 ) ?;
461462
462- self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( b_vid, b_ty) ;
463+ // Constrain `b_vid` to the generalized type `b_ty`.
464+ if let & ty:: Infer ( TyVar ( b_ty_vid) ) = b_ty. kind ( ) {
465+ self . infcx . inner . borrow_mut ( ) . type_variables ( ) . equate ( b_vid, b_ty_vid) ;
466+ } else {
467+ self . infcx . inner . borrow_mut ( ) . type_variables ( ) . instantiate ( b_vid, b_ty) ;
468+ }
463469
464470 if needs_wf {
465471 self . obligations . push ( Obligation :: new (
@@ -484,31 +490,46 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
484490 // cyclic type. We instead delay the unification in case
485491 // the alias can be normalized to something which does not
486492 // mention `?0`.
487-
488- // FIXME(-Ztrait-solver=next): replace this with `AliasRelate`
489- let & ty:: Alias ( kind, data) = a_ty. kind ( ) else {
490- bug ! ( "generalization should only result in infer vars for aliases" ) ;
491- } ;
492- if !self . infcx . next_trait_solver ( ) {
493- // The old solver only accepts projection predicates for associated types.
494- match kind {
495- ty:: AliasKind :: Projection => { }
496- ty:: AliasKind :: Inherent | ty:: AliasKind :: Weak | ty:: AliasKind :: Opaque => {
497- return Err ( TypeError :: CyclicTy ( a_ty) ) ;
493+ if self . infcx . next_trait_solver ( ) {
494+ let ( lhs, rhs, direction) = match ambient_variance {
495+ ty:: Variance :: Invariant => {
496+ ( a_ty. into ( ) , b_ty. into ( ) , AliasRelationDirection :: Equate )
497+ }
498+ ty:: Variance :: Covariant => {
499+ ( a_ty. into ( ) , b_ty. into ( ) , AliasRelationDirection :: Subtype )
500+ }
501+ ty:: Variance :: Contravariant => {
502+ ( b_ty. into ( ) , a_ty. into ( ) , AliasRelationDirection :: Subtype )
503+ }
504+ ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
505+ } ;
506+ self . obligations . push ( Obligation :: new (
507+ self . tcx ( ) ,
508+ self . trace . cause . clone ( ) ,
509+ self . param_env ,
510+ ty:: PredicateKind :: AliasRelate ( lhs, rhs, direction) ,
511+ ) ) ;
512+ } else {
513+ match a_ty. kind ( ) {
514+ & ty:: Alias ( ty:: AliasKind :: Projection , data) => {
515+ // FIXME: This does not handle subtyping correctly, we could
516+ // instead create a new inference variable for `a_ty`, emitting
517+ // `Projection(a_ty, a_infer)` and `a_infer <: b_ty`.
518+ self . obligations . push ( Obligation :: new (
519+ self . tcx ( ) ,
520+ self . trace . cause . clone ( ) ,
521+ self . param_env ,
522+ ty:: ProjectionPredicate { projection_ty : data, term : b_ty. into ( ) } ,
523+ ) )
498524 }
525+ // The old solver only accepts projection predicates for associated types.
526+ ty:: Alias (
527+ ty:: AliasKind :: Inherent | ty:: AliasKind :: Weak | ty:: AliasKind :: Opaque ,
528+ _,
529+ ) => return Err ( TypeError :: CyclicTy ( a_ty) ) ,
530+ _ => bug ! ( "generalizated `{a_ty:?} to infer, not an alias" ) ,
499531 }
500532 }
501-
502- // FIXME: This does not handle subtyping correctly, we should switch to
503- // alias-relate in the new solver and could instead create a new inference
504- // variable for `a_ty`, emitting `Projection(a_ty, a_infer)` and
505- // `a_infer <: b_ty`.
506- self . obligations . push ( Obligation :: new (
507- self . tcx ( ) ,
508- self . trace . cause . clone ( ) ,
509- self . param_env ,
510- ty:: ProjectionPredicate { projection_ty : data, term : b_ty. into ( ) } ,
511- ) )
512533 } else {
513534 match ambient_variance {
514535 ty:: Variance :: Invariant => self . equate ( a_is_expected) . relate ( a_ty, b_ty) ,
@@ -519,9 +540,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
519540 a_ty,
520541 b_ty,
521542 ) ,
522- ty:: Variance :: Bivariant => {
523- unreachable ! ( "no code should be generalizing bivariantly (currently)" )
524- }
543+ ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
525544 } ?;
526545 }
527546
0 commit comments