@@ -34,8 +34,8 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVa
3434use rustc_middle:: infer:: unify_key:: { ConstVariableOrigin , ConstVariableOriginKind } ;
3535use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
3636use rustc_middle:: ty:: relate:: { RelateResult , TypeRelation } ;
37- use rustc_middle:: ty:: TyVar ;
3837use rustc_middle:: ty:: { self , InferConst , ToPredicate , Ty , TyCtxt , TypeVisitableExt } ;
38+ use rustc_middle:: ty:: { AliasRelationDirection , TyVar } ;
3939use rustc_middle:: ty:: { IntType , UintType } ;
4040use rustc_span:: DUMMY_SP ;
4141
@@ -490,31 +490,47 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
490490 // cyclic type. We instead delay the unification in case
491491 // the alias can be normalized to something which does not
492492 // mention `?0`.
493-
494- // FIXME(-Ztrait-solver=next): replace this with `AliasRelate`
495- let & ty:: Alias ( kind, data) = a_ty. kind ( ) else {
496- bug ! ( "generalization should only result in infer vars for aliases" ) ;
497- } ;
498- if !self . infcx . next_trait_solver ( ) {
499- // The old solver only accepts projection predicates for associated types.
500- match kind {
501- ty:: AliasKind :: Projection => { }
502- ty:: AliasKind :: Inherent | ty:: AliasKind :: Weak | ty:: AliasKind :: Opaque => {
503- 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 )
504503 }
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 should switch to
516+ // alias-relate in the new solver and could instead create a new inference
517+ // variable for `a_ty`, emitting `Projection(a_ty, a_infer)` and
518+ // `a_infer <: b_ty`.
519+ self . obligations . push ( Obligation :: new (
520+ self . tcx ( ) ,
521+ self . trace . cause . clone ( ) ,
522+ self . param_env ,
523+ ty:: ProjectionPredicate { projection_ty : data, term : b_ty. into ( ) } ,
524+ ) )
525+ }
526+ // The old solver only accepts projection predicates for associated types.
527+ ty:: Alias (
528+ ty:: AliasKind :: Inherent | ty:: AliasKind :: Weak | ty:: AliasKind :: Opaque ,
529+ _,
530+ ) => return Err ( TypeError :: CyclicTy ( a_ty) ) ,
531+ _ => bug ! ( "generalizated `{a_ty:?} to infer, not an alias" ) ,
505532 }
506533 }
507-
508- // FIXME: This does not handle subtyping correctly, we should switch to
509- // alias-relate in the new solver and could instead create a new inference
510- // variable for `a_ty`, emitting `Projection(a_ty, a_infer)` and
511- // `a_infer <: b_ty`.
512- self . obligations . push ( Obligation :: new (
513- self . tcx ( ) ,
514- self . trace . cause . clone ( ) ,
515- self . param_env ,
516- ty:: ProjectionPredicate { projection_ty : data, term : b_ty. into ( ) } ,
517- ) )
518534 } else {
519535 match ambient_variance {
520536 ty:: Variance :: Invariant => self . equate ( a_is_expected) . relate ( a_ty, b_ty) ,
@@ -525,9 +541,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
525541 a_ty,
526542 b_ty,
527543 ) ,
528- ty:: Variance :: Bivariant => {
529- unreachable ! ( "no code should be generalizing bivariantly (currently)" )
530- }
544+ ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
531545 } ?;
532546 }
533547
0 commit comments