diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 5e4d82b6fd5..ca650207287 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -221,8 +221,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::Ref(region, ty, mutbl) => { - let contra = self.contravariant(variance); - self.add_constraints_from_region(current, region, contra); + self.add_constraints_from_region(current, region, variance); self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance); } @@ -254,9 +253,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { } ty::Dynamic(data, r, _) => { - // The type `Foo` is contravariant w/r/t `'a`: - let contra = self.contravariant(variance); - self.add_constraints_from_region(current, r, contra); + // The type `Foo` is covariant w/r/t `'a`: + self.add_constraints_from_region(current, r, variance); if let Some(poly_trait_ref) = data.principal() { self.add_constraints_from_invariant_substs( diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 21b68ce9989..b92b162a978 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -79,7 +79,8 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { debug!("{}.regions({:?}, {:?})", self.tag(), a, b); let origin = Subtype(Box::new(self.fields.trace.clone())); - Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions( + // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8 + Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions( self.tcx(), origin, a, diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index c07ac1d3ace..f6e0554fd1f 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -79,7 +79,8 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { debug!("{}.regions({:?}, {:?})", self.tag(), a, b); let origin = Subtype(Box::new(self.fields.trace.clone())); - Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions( + // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8 + Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions( self.tcx(), origin, a, diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index f235cb5ab45..f83219b8ee2 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -663,13 +663,13 @@ where debug!(?v_b); if self.ambient_covariance() { - // Covariance: a <= b. Hence, `b: a`. - self.push_outlives(v_b, v_a, self.ambient_variance_info); + // Covariant: &'a u8 <: &'b u8. Hence, `'a: 'b`. + self.push_outlives(v_a, v_b, self.ambient_variance_info); } if self.ambient_contravariance() { - // Contravariant: b <= a. Hence, `a: b`. - self.push_outlives(v_a, v_b, self.ambient_variance_info); + // Contravariant: &'b u8 <: &'a u8. Hence, `'b: 'a`. + self.push_outlives(v_b, v_a, self.ambient_variance_info); } Ok(a) diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index bd38b52ba34..51c34f0d55f 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -191,12 +191,13 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { // from the "cause" field, we could perhaps give more tailored // error messages. let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone())); + // Subtype(&'a u8, &'b u8) => Outlives('a: 'b) => SubRegion('b, 'a) self.fields .infcx .inner .borrow_mut() .unwrap_region_constraints() - .make_subregion(origin, a, b); + .make_subregion(origin, b, a); Ok(a) } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 65fd8d9753d..114a91de5d3 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -443,12 +443,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( if a_repr == b_repr => { let region_bound = relation.with_cause(Cause::ExistentialRegionBound, |relation| { - relation.relate_with_variance( - ty::Contravariant, - ty::VarianceDiagInfo::default(), - a_region, - b_region, - ) + relation.relate(a_region, b_region) })?; Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound, a_repr)) } @@ -487,12 +482,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( } (&ty::Ref(a_r, a_ty, a_mutbl), &ty::Ref(b_r, b_ty, b_mutbl)) => { - let r = relation.relate_with_variance( - ty::Contravariant, - ty::VarianceDiagInfo::default(), - a_r, - b_r, - )?; + let r = relation.relate(a_r, b_r)?; let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl }; let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl }; let mt = relate_type_and_mut(relation, a_mt, b_mt, a)?; diff --git a/tests/ui/error-codes/E0208.rs b/tests/ui/error-codes/E0208.rs index c67d42889d6..74c138af483 100644 --- a/tests/ui/error-codes/E0208.rs +++ b/tests/ui/error-codes/E0208.rs @@ -1,7 +1,7 @@ #![feature(rustc_attrs)] #[rustc_variance] -struct Foo<'a, T> { //~ ERROR [-, o] +struct Foo<'a, T> { //~ ERROR [+, o] t: &'a mut T, } diff --git a/tests/ui/error-codes/E0208.stderr b/tests/ui/error-codes/E0208.stderr index dbbb41e7950..2c7072a7e76 100644 --- a/tests/ui/error-codes/E0208.stderr +++ b/tests/ui/error-codes/E0208.stderr @@ -1,4 +1,4 @@ -error: [-, o] +error: [+, o] --> $DIR/E0208.rs:4:1 | LL | struct Foo<'a, T> { diff --git a/tests/ui/variance/variance-associated-types.rs b/tests/ui/variance/variance-associated-types.rs index 1165fb53c73..ecb0821827d 100644 --- a/tests/ui/variance/variance-associated-types.rs +++ b/tests/ui/variance/variance-associated-types.rs @@ -10,7 +10,7 @@ trait Trait<'a> { } #[rustc_variance] -struct Foo<'a, T : Trait<'a>> { //~ ERROR [-, +] +struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +] field: (T, &'a ()) } diff --git a/tests/ui/variance/variance-associated-types.stderr b/tests/ui/variance/variance-associated-types.stderr index 51f17c7c228..70cb246f6e9 100644 --- a/tests/ui/variance/variance-associated-types.stderr +++ b/tests/ui/variance/variance-associated-types.stderr @@ -1,4 +1,4 @@ -error: [-, +] +error: [+, +] --> $DIR/variance-associated-types.rs:13:1 | LL | struct Foo<'a, T : Trait<'a>> { diff --git a/tests/ui/variance/variance-regions-direct.rs b/tests/ui/variance/variance-regions-direct.rs index 3f34e7655f3..39ea77a8aa2 100644 --- a/tests/ui/variance/variance-regions-direct.rs +++ b/tests/ui/variance/variance-regions-direct.rs @@ -6,7 +6,7 @@ // Regions that just appear in normal spots are contravariant: #[rustc_variance] -struct Test2<'a, 'b, 'c> { //~ ERROR [-, -, -] +struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +] x: &'a isize, y: &'b [isize], c: &'c str @@ -15,7 +15,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR [-, -, -] // Those same annotations in function arguments become covariant: #[rustc_variance] -struct Test3<'a, 'b, 'c> { //~ ERROR [+, +, +] +struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -] x: extern "Rust" fn(&'a isize), y: extern "Rust" fn(&'b [isize]), c: extern "Rust" fn(&'c str), @@ -24,7 +24,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR [+, +, +] // Mutability induces invariance: #[rustc_variance] -struct Test4<'a, 'b:'a> { //~ ERROR [-, o] +struct Test4<'a, 'b:'a> { //~ ERROR [+, o] x: &'a mut &'b isize, } @@ -32,7 +32,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR [-, o] // contravariant context: #[rustc_variance] -struct Test5<'a, 'b:'a> { //~ ERROR [+, o] +struct Test5<'a, 'b:'a> { //~ ERROR [-, o] x: extern "Rust" fn(&'a mut &'b isize), } @@ -42,7 +42,7 @@ struct Test5<'a, 'b:'a> { //~ ERROR [+, o] // argument list occurs in an invariant context. #[rustc_variance] -struct Test6<'a, 'b:'a> { //~ ERROR [-, o] +struct Test6<'a, 'b:'a> { //~ ERROR [+, o] x: &'a mut extern "Rust" fn(&'b isize), } @@ -56,7 +56,7 @@ struct Test7<'a> { //~ ERROR [*] // Try enums too. #[rustc_variance] -enum Test8<'a, 'b, 'c:'b> { //~ ERROR [+, -, o] +enum Test8<'a, 'b, 'c:'b> { //~ ERROR [-, +, o] Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), Test8C(&'b mut &'c str), diff --git a/tests/ui/variance/variance-regions-direct.stderr b/tests/ui/variance/variance-regions-direct.stderr index eda02e9b03b..c55730296f1 100644 --- a/tests/ui/variance/variance-regions-direct.stderr +++ b/tests/ui/variance/variance-regions-direct.stderr @@ -1,28 +1,28 @@ -error: [-, -, -] +error: [+, +, +] --> $DIR/variance-regions-direct.rs:9:1 | LL | struct Test2<'a, 'b, 'c> { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: [+, +, +] +error: [-, -, -] --> $DIR/variance-regions-direct.rs:18:1 | LL | struct Test3<'a, 'b, 'c> { | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: [-, o] +error: [+, o] --> $DIR/variance-regions-direct.rs:27:1 | LL | struct Test4<'a, 'b:'a> { | ^^^^^^^^^^^^^^^^^^^^^^^ -error: [+, o] +error: [-, o] --> $DIR/variance-regions-direct.rs:35:1 | LL | struct Test5<'a, 'b:'a> { | ^^^^^^^^^^^^^^^^^^^^^^^ -error: [-, o] +error: [+, o] --> $DIR/variance-regions-direct.rs:45:1 | LL | struct Test6<'a, 'b:'a> { @@ -34,7 +34,7 @@ error: [*] LL | struct Test7<'a> { | ^^^^^^^^^^^^^^^^ -error: [+, -, o] +error: [-, +, o] --> $DIR/variance-regions-direct.rs:59:1 | LL | enum Test8<'a, 'b, 'c:'b> { diff --git a/tests/ui/variance/variance-regions-indirect.rs b/tests/ui/variance/variance-regions-indirect.rs index f84f25ada14..0d00535fef1 100644 --- a/tests/ui/variance/variance-regions-indirect.rs +++ b/tests/ui/variance/variance-regions-indirect.rs @@ -5,14 +5,14 @@ #![feature(rustc_attrs)] #[rustc_variance] -enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [+, -, o, *] +enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *] Test8A(extern "Rust" fn(&'a isize)), Test8B(&'b [isize]), Test8C(&'b mut &'c str), } #[rustc_variance] -struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, -, +] +struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -] f: Base<'z, 'y, 'x, 'w> } @@ -22,12 +22,12 @@ struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *] } #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) -struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, -, *] +struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, +, *] f: Base<'a, 'b, 'a, 'c> } #[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here) -struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [+, -, o] +struct Derived4<'a, 'b, 'c:'b> { //~ ERROR [-, +, o] f: Base<'a, 'b, 'c, 'a> } diff --git a/tests/ui/variance/variance-regions-indirect.stderr b/tests/ui/variance/variance-regions-indirect.stderr index fa2f4d507f3..edf2626d598 100644 --- a/tests/ui/variance/variance-regions-indirect.stderr +++ b/tests/ui/variance/variance-regions-indirect.stderr @@ -1,10 +1,10 @@ -error: [+, -, o, *] +error: [-, +, o, *] --> $DIR/variance-regions-indirect.rs:8:1 | LL | enum Base<'a, 'b, 'c:'b, 'd> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: [*, o, -, +] +error: [*, o, +, -] --> $DIR/variance-regions-indirect.rs:15:1 | LL | struct Derived1<'w, 'x:'y, 'y, 'z> { @@ -16,13 +16,13 @@ error: [o, o, *] LL | struct Derived2<'a, 'b:'a, 'c> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: [o, -, *] +error: [o, +, *] --> $DIR/variance-regions-indirect.rs:25:1 | LL | struct Derived3<'a:'b, 'b, 'c> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: [+, -, o] +error: [-, +, o] --> $DIR/variance-regions-indirect.rs:30:1 | LL | struct Derived4<'a, 'b, 'c:'b> { diff --git a/tests/ui/variance/variance-trait-object-bound.rs b/tests/ui/variance/variance-trait-object-bound.rs index ec3c973bc76..11303c46520 100644 --- a/tests/ui/variance/variance-trait-object-bound.rs +++ b/tests/ui/variance/variance-trait-object-bound.rs @@ -11,7 +11,7 @@ use std::mem; trait T { fn foo(&self); } #[rustc_variance] -struct TOption<'a> { //~ ERROR [-] +struct TOption<'a> { //~ ERROR [+] v: Option>, } diff --git a/tests/ui/variance/variance-trait-object-bound.stderr b/tests/ui/variance/variance-trait-object-bound.stderr index 7c46b553f43..bfcc8d4a1d1 100644 --- a/tests/ui/variance/variance-trait-object-bound.stderr +++ b/tests/ui/variance/variance-trait-object-bound.stderr @@ -1,4 +1,4 @@ -error: [-] +error: [+] --> $DIR/variance-trait-object-bound.rs:14:1 | LL | struct TOption<'a> { diff --git a/tests/ui/variance/variance-types.rs b/tests/ui/variance/variance-types.rs index b9b6d9c9bb5..cfc03b75473 100644 --- a/tests/ui/variance/variance-types.rs +++ b/tests/ui/variance/variance-types.rs @@ -7,7 +7,7 @@ use std::cell::Cell; // not considered bivariant. #[rustc_variance] -struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [-, o, o] +struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [+, o, o] t: &'a mut (A,B) } diff --git a/tests/ui/variance/variance-types.stderr b/tests/ui/variance/variance-types.stderr index 9f7f1d9b0e3..0fda4b8036e 100644 --- a/tests/ui/variance/variance-types.stderr +++ b/tests/ui/variance/variance-types.stderr @@ -1,4 +1,4 @@ -error: [-, o, o] +error: [+, o, o] --> $DIR/variance-types.rs:10:1 | LL | struct InvariantMut<'a,A:'a,B:'a> {