@@ -1059,14 +1059,29 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
1059
1059
}
1060
1060
1061
1061
ty:: Predicate :: Equate ( ty:: Binder ( ref data) ) => {
1062
- self . add_constraints_from_ty ( generics, data. 0 , variance) ;
1063
- self . add_constraints_from_ty ( generics, data. 1 , variance) ;
1062
+ // A == B is only true if A and B are the same
1063
+ // types, not subtypes of one another, so this is
1064
+ // an invariant position:
1065
+ self . add_constraints_from_ty ( generics, data. 0 , self . invariant ) ;
1066
+ self . add_constraints_from_ty ( generics, data. 1 , self . invariant ) ;
1064
1067
}
1065
1068
1066
1069
ty:: Predicate :: TypeOutlives ( ty:: Binder ( ref data) ) => {
1067
- self . add_constraints_from_ty ( generics, data. 0 , variance) ;
1070
+ // Why contravariant on both? Let's consider:
1071
+ //
1072
+ // Under what conditions is `(T:'t) <: (U:'u)`,
1073
+ // meaning that `(T:'t) => (U:'u)`. The answer is
1074
+ // if `U <: T` or `'u <= 't`. Let's see some examples:
1075
+ //
1076
+ // (T: 'big) => (T: 'small)
1077
+ // where 'small <= 'big
1078
+ //
1079
+ // (&'small Foo: 't) => (&'big Foo: 't)
1080
+ // where 'small <= 'big
1081
+ // note that &'big Foo <: &'small Foo
1068
1082
1069
1083
let variance_r = self . xform ( variance, self . contravariant ) ;
1084
+ self . add_constraints_from_ty ( generics, data. 0 , variance_r) ;
1070
1085
self . add_constraints_from_region ( generics, data. 1 , variance_r) ;
1071
1086
}
1072
1087
@@ -1084,6 +1099,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
1084
1099
& * data. projection_ty . trait_ref ,
1085
1100
variance) ;
1086
1101
1102
+ // as the equality predicate above, a binder is a
1103
+ // type equality relation, not a subtyping
1104
+ // relation
1087
1105
self . add_constraints_from_ty ( generics, data. ty , self . invariant ) ;
1088
1106
}
1089
1107
}
0 commit comments