@@ -26,13 +26,13 @@ impl<'tcx> InferCtxt<'tcx> {
26
26
/// This is *not* expected to be used anywhere except for an implementation of
27
27
/// `TypeRelation`. Do not use this, and instead please use `At::eq`, for all
28
28
/// 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) ) ]
30
30
pub fn instantiate_ty_var < R : ObligationEmittingRelation < ' tcx > > (
31
31
& self ,
32
32
relation : & mut R ,
33
33
target_is_expected : bool ,
34
34
target_vid : ty:: TyVid ,
35
- ambient_variance : ty:: Variance ,
35
+ instantiation_variance : ty:: Variance ,
36
36
source_ty : Ty < ' tcx > ,
37
37
) -> RelateResult < ' tcx , ( ) > {
38
38
debug_assert ! ( self . inner. borrow_mut( ) . type_variables( ) . probe( target_vid) . is_unknown( ) ) ;
@@ -46,7 +46,7 @@ impl<'tcx> InferCtxt<'tcx> {
46
46
//
47
47
// We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
48
48
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) ?;
50
50
51
51
// Constrain `b_vid` to the generalized type `generalized_ty`.
52
52
if let & ty:: Infer ( ty:: TyVar ( generalized_vid) ) = generalized_ty. kind ( ) {
@@ -73,7 +73,7 @@ impl<'tcx> InferCtxt<'tcx> {
73
73
// the alias can be normalized to something which does not
74
74
// mention `?0`.
75
75
if self . next_trait_solver ( ) {
76
- let ( lhs, rhs, direction) = match ambient_variance {
76
+ let ( lhs, rhs, direction) = match instantiation_variance {
77
77
ty:: Variance :: Invariant => {
78
78
( generalized_ty. into ( ) , source_ty. into ( ) , AliasRelationDirection :: Equate )
79
79
}
@@ -106,22 +106,28 @@ impl<'tcx> InferCtxt<'tcx> {
106
106
}
107
107
}
108
108
} 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 (not code)
116
+ // ?a rel B
117
+ // instantiate_ty_var(?a, B) # expected and variance not flipped
118
+ // B' rel B
119
+ // ```
120
+ // or
121
+ // ```ignore (not code)
122
+ // A rel ?b
123
+ // instantiate_ty_var(?b, A) # expected and variance flipped
124
+ // A rel A'
125
+ // ```
111
126
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) ?;
118
128
} 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) ?;
125
131
}
126
132
}
127
133
0 commit comments