@@ -35,6 +35,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
35
35
use rustc_middle:: ty:: error:: { ExpectedFound , TypeError } ;
36
36
use rustc_middle:: ty:: relate:: { RelateResult , TypeRelation } ;
37
37
use rustc_middle:: ty:: { self , InferConst , ToPredicate , Ty , TyCtxt , TypeVisitableExt } ;
38
+ use rustc_middle:: ty:: { AliasRelationDirection , TyVar } ;
38
39
use rustc_middle:: ty:: { IntType , UintType } ;
39
40
use rustc_span:: DUMMY_SP ;
40
41
@@ -459,7 +460,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
459
460
ambient_variance,
460
461
) ?;
461
462
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
+ }
463
469
464
470
if needs_wf {
465
471
self . obligations . push ( Obligation :: new (
@@ -484,31 +490,46 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
484
490
// cyclic type. We instead delay the unification in case
485
491
// the alias can be normalized to something which does not
486
492
// 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
+ ) )
498
524
}
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" ) ,
499
531
}
500
532
}
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
- ) )
512
533
} else {
513
534
match ambient_variance {
514
535
ty:: Variance :: Invariant => self . equate ( a_is_expected) . relate ( a_ty, b_ty) ,
@@ -519,9 +540,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
519
540
a_ty,
520
541
b_ty,
521
542
) ,
522
- ty:: Variance :: Bivariant => {
523
- unreachable ! ( "no code should be generalizing bivariantly (currently)" )
524
- }
543
+ ty:: Variance :: Bivariant => unreachable ! ( "bivariant generalization" ) ,
525
544
} ?;
526
545
}
527
546
0 commit comments