@@ -26,13 +26,13 @@ impl<'tcx> InferCtxt<'tcx> {
2626 /// This is *not* expected to be used anywhere except for an implementation of
2727 /// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
2828 /// other usecases (i.e. setting the value of a type var).
29- #[ instrument( level = "debug" , skip( self , relation, target_is_expected ) ) ]
29+ #[ instrument( level = "debug" , skip( self , relation) ) ]
3030 pub fn instantiate_ty_var < R : ObligationEmittingRelation < ' tcx > > (
3131 & self ,
3232 relation : & mut R ,
3333 target_is_expected : bool ,
3434 target_vid : ty:: TyVid ,
35- ambient_variance : ty:: Variance ,
35+ instantiation_variance : ty:: Variance ,
3636 source_ty : Ty < ' tcx > ,
3737 ) -> RelateResult < ' tcx , ( ) > {
3838 debug_assert ! ( self . inner. borrow_mut( ) . type_variables( ) . probe( target_vid) . is_unknown( ) ) ;
@@ -46,7 +46,7 @@ impl<'tcx> InferCtxt<'tcx> {
4646 //
4747 // We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
4848 let Generalization { value_may_be_infer : generalized_ty, has_unconstrained_ty_var } =
49- self . generalize ( relation. span ( ) , target_vid, ambient_variance , source_ty) ?;
49+ self . generalize ( relation. span ( ) , target_vid, instantiation_variance , source_ty) ?;
5050
5151 // Constrain `b_vid` to the generalized type `generalized_ty`.
5252 if let & ty:: Infer ( ty:: TyVar ( generalized_vid) ) = generalized_ty. kind ( ) {
@@ -73,7 +73,7 @@ impl<'tcx> InferCtxt<'tcx> {
7373 // the alias can be normalized to something which does not
7474 // mention `?0`.
7575 if self . next_trait_solver ( ) {
76- let ( lhs, rhs, direction) = match ambient_variance {
76+ let ( lhs, rhs, direction) = match instantiation_variance {
7777 ty:: Variance :: Invariant => {
7878 ( generalized_ty. into ( ) , source_ty. into ( ) , AliasRelationDirection :: Equate )
7979 }
@@ -106,22 +106,28 @@ impl<'tcx> InferCtxt<'tcx> {
106106 }
107107 }
108108 } else {
109- // HACK: make sure that we `a_is_expected` continues to be
110- // correct when relating the generalized type with the source.
109+ // NOTE: The `instantiation_variance` is not the same variance as
110+ // used by the relation. When instantiating `b`, `target_is_expected`
111+ // is flipped and the `instantion_variance` is also flipped. To
112+ // constrain the `generalized_ty` while using the original relation,
113+ // we therefore only have to flip the arguments.
114+ //
115+ // ```ignore
116+ // ?a rel B
117+ // instantiate_ty_var(?a, B) # expected and variance not flipped
118+ // B' rel B
119+ // ```
120+ // or
121+ // ```ignore
122+ // A rel ?b
123+ // instantiate_ty_var(?b, A) # expected and variance flipped
124+ // A rel A'
125+ // ```
111126 if target_is_expected == relation. a_is_expected ( ) {
112- relation. relate_with_variance (
113- ambient_variance,
114- ty:: VarianceDiagInfo :: default ( ) ,
115- generalized_ty,
116- source_ty,
117- ) ?;
127+ relation. relate ( generalized_ty, source_ty) ?;
118128 } else {
119- relation. relate_with_variance (
120- ambient_variance. xform ( ty:: Contravariant ) ,
121- ty:: VarianceDiagInfo :: default ( ) ,
122- source_ty,
123- generalized_ty,
124- ) ?;
129+ debug ! ( "flip relation" ) ;
130+ relation. relate ( source_ty, generalized_ty) ?;
125131 }
126132 }
127133
0 commit comments