Skip to content

Commit a5caa98

Browse files
authored
Rollup merge of #107339 - aliemjay:covariant, r=lcnr
internally change regions to be covariant Surprisingly, we consider the reference type `&'a T` to be contravaraint in its lifetime parameter. This is confusing and conflicts with the documentation we have in the reference, rustnomicon, and rustc-dev-guide. This also arguably not the correct use of terminology since we can use `&'static u8` in a place where `&' a u8` is expected, this implies that `&'static u8 <: &' a u8` and consequently `'static <: ' a`, hence covariance. Because of this, when relating two types, we used to switch the argument positions in a confusing way: `Subtype(&'a u8 <: &'b u8) => Subtype('b <: 'a) => Outlives('a: 'b) => RegionSubRegion('b <= 'a)` The reason for the current behavior is probably that we wanted `Subtype('b <: 'a)` and `RegionSubRegion('b <= 'a)` to be equivalent, but I don' t think this is a good reason since these relations are sufficiently different in that the first is a relation in the subtyping lattice and is intrinsic to the type-systems, while the the second relation is an implementation detail of regionck. This PR changes this behavior to use covariance, so.. `Subtype(&'a u8 <: &'b u8) => Subtype('a <: 'b) => Outlives('a: 'b) => RegionSubRegion('b <= 'a) ` Resolves #103676 r? `@lcnr`
2 parents fa2cd94 + 43cb610 commit a5caa98

18 files changed

+43
-52
lines changed

compiler/rustc_hir_analysis/src/variance/constraints.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
225225
}
226226

227227
ty::Ref(region, ty, mutbl) => {
228-
let contra = self.contravariant(variance);
229-
self.add_constraints_from_region(current, region, contra);
228+
self.add_constraints_from_region(current, region, variance);
230229
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
231230
}
232231

@@ -258,9 +257,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
258257
}
259258

260259
ty::Dynamic(data, r, _) => {
261-
// The type `Foo<T+'a>` is contravariant w/r/t `'a`:
262-
let contra = self.contravariant(variance);
263-
self.add_constraints_from_region(current, r, contra);
260+
// The type `dyn Trait<T> +'a` is covariant w/r/t `'a`:
261+
self.add_constraints_from_region(current, r, variance);
264262

265263
if let Some(poly_trait_ref) = data.principal() {
266264
self.add_constraints_from_invariant_substs(

compiler/rustc_infer/src/infer/glb.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
7979
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
8080

8181
let origin = Subtype(Box::new(self.fields.trace.clone()));
82-
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
82+
// GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
83+
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
8384
self.tcx(),
8485
origin,
8586
a,

compiler/rustc_infer/src/infer/lub.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
7979
debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
8080

8181
let origin = Subtype(Box::new(self.fields.trace.clone()));
82-
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
82+
// LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
83+
Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
8384
self.tcx(),
8485
origin,
8586
a,

compiler/rustc_infer/src/infer/nll_relate/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,13 +663,13 @@ where
663663
debug!(?v_b);
664664

665665
if self.ambient_covariance() {
666-
// Covariance: a <= b. Hence, `b: a`.
667-
self.push_outlives(v_b, v_a, self.ambient_variance_info);
666+
// Covariant: &'a u8 <: &'b u8. Hence, `'a: 'b`.
667+
self.push_outlives(v_a, v_b, self.ambient_variance_info);
668668
}
669669

670670
if self.ambient_contravariance() {
671-
// Contravariant: b <= a. Hence, `a: b`.
672-
self.push_outlives(v_a, v_b, self.ambient_variance_info);
671+
// Contravariant: &'b u8 <: &'a u8. Hence, `'b: 'a`.
672+
self.push_outlives(v_b, v_a, self.ambient_variance_info);
673673
}
674674

675675
Ok(a)

compiler/rustc_infer/src/infer/sub.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,12 +191,13 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
191191
// from the "cause" field, we could perhaps give more tailored
192192
// error messages.
193193
let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
194+
// Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a)
194195
self.fields
195196
.infcx
196197
.inner
197198
.borrow_mut()
198199
.unwrap_region_constraints()
199-
.make_subregion(origin, a, b);
200+
.make_subregion(origin, b, a);
200201

201202
Ok(a)
202203
}

compiler/rustc_middle/src/ty/relate.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -443,12 +443,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
443443
if a_repr == b_repr =>
444444
{
445445
let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| {
446-
relation.relate_with_variance(
447-
ty::Contravariant,
448-
ty::VarianceDiagInfo::default(),
449-
a_region,
450-
b_region,
451-
)
446+
relation.relate(a_region, b_region)
452447
})?;
453448
Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound, a_repr))
454449
}
@@ -497,12 +492,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
497492
}
498493

499494
(&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => {
500-
let r = relation.relate_with_variance(
501-
ty::Contravariant,
502-
ty::VarianceDiagInfo::default(),
503-
a_r,
504-
b_r,
505-
)?;
495+
let r = relation.relate(a_r, b_r)?;
506496
let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl };
507497
let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl };
508498
let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?;

tests/ui/error-codes/E0208.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![feature(rustc_attrs)]
22

33
#[rustc_variance]
4-
struct Foo<'a, T> { //~ ERROR [-, o]
4+
struct Foo<'a, T> { //~ ERROR [+, o]
55
t: &'a mut T,
66
}
77

tests/ui/error-codes/E0208.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: [-, o]
1+
error: [+, o]
22
--> $DIR/E0208.rs:4:1
33
|
44
LL | struct Foo<'a, T> {

tests/ui/variance/variance-associated-types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ trait Trait<'a> {
1010
}
1111

1212
#[rustc_variance]
13-
struct Foo<'a, T : Trait<'a>> { //~ ERROR [-, +]
13+
struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +]
1414
field: (T, &'a ())
1515
}
1616

tests/ui/variance/variance-associated-types.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: [-, +]
1+
error: [+, +]
22
--> $DIR/variance-associated-types.rs:13:1
33
|
44
LL | struct Foo<'a, T : Trait<'a>> {

0 commit comments

Comments
 (0)