1
Fork 0

Rollup merge of #129429 - cjgillot:named-variance, r=compiler-errors

Print the generic parameter along with the variance in dumps.

This allows to make sure we are testing what we think we are testing.

While the tests are correct, I discovered that opaque duplicated args are in the reverse declaration order.
This commit is contained in:
Trevor Gross 2024-08-24 21:03:32 -05:00 committed by GitHub
commit 2269381e0a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 158 additions and 140 deletions

View file

@ -1,18 +1,36 @@
use std::fmt::Write;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::{GenericArgs, TyCtxt};
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
let variances = tcx.variances_of(def_id);
let generics = GenericArgs::identity_for_item(tcx, def_id);
// 7 = 2-letter parameter + ": " + 1-letter variance + ", "
let mut ret = String::with_capacity(2 + 7 * variances.len());
ret.push('[');
for (arg, variance) in generics.iter().zip(variances.iter()) {
write!(ret, "{arg}: {variance:?}, ").unwrap();
}
// Remove trailing `, `.
if !variances.is_empty() {
ret.pop();
ret.pop();
}
ret.push(']');
ret
}
pub(crate) fn variances(tcx: TyCtxt<'_>) { pub(crate) fn variances(tcx: TyCtxt<'_>) {
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) { if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
for id in tcx.hir().items() { for id in tcx.hir().items() {
let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue }; let DefKind::OpaqueTy = tcx.def_kind(id.owner_id) else { continue };
let variances = tcx.variances_of(id.owner_id);
tcx.dcx().emit_err(crate::errors::VariancesOf { tcx.dcx().emit_err(crate::errors::VariancesOf {
span: tcx.def_span(id.owner_id), span: tcx.def_span(id.owner_id),
variances: format!("{variances:?}"), variances: format_variances(tcx, id.owner_id.def_id),
}); });
} }
} }
@ -22,11 +40,9 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
continue; continue;
} }
let variances = tcx.variances_of(id.owner_id);
tcx.dcx().emit_err(crate::errors::VariancesOf { tcx.dcx().emit_err(crate::errors::VariancesOf {
span: tcx.def_span(id.owner_id), span: tcx.def_span(id.owner_id),
variances: format!("{variances:?}"), variances: format_variances(tcx, id.owner_id.def_id),
}); });
} }
} }

View file

@ -1,7 +1,7 @@
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#[rustc_variance] #[rustc_variance]
struct Foo<'a, T> { //~ ERROR [+, o] struct Foo<'a, T> { //~ ERROR ['a: +, T: o]
t: &'a mut T, t: &'a mut T,
} }

View file

@ -1,4 +1,4 @@
error: [+, o] error: ['a: +, T: o]
--> $DIR/E0208.rs:4:1 --> $DIR/E0208.rs:4:1
| |
LL | struct Foo<'a, T> { LL | struct Foo<'a, T> {

View file

@ -6,13 +6,13 @@ trait Bar<'a> {
} }
fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> { fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
//~^ ERROR [o, o] //~^ ERROR ['a: o, T: o]
// captures both T and 'a invariantly // captures both T and 'a invariantly
() ()
} }
fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a { fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {
//~^ ERROR [o, o, o] //~^ ERROR ['a: o, T: o, 'a: o]
// captures both T and 'a invariantly, and also duplicates `'a` // captures both T and 'a invariantly, and also duplicates `'a`
// i.e. the opaque looks like `impl Into<<T as Bar<'a>>::Assoc> + 'a_duplicated` // i.e. the opaque looks like `impl Into<<T as Bar<'a>>::Assoc> + 'a_duplicated`
() ()

View file

@ -1,10 +1,10 @@
error: [o, o] error: ['a: o, T: o]
--> $DIR/capture-lifetime-not-in-hir.rs:8:29 --> $DIR/capture-lifetime-not-in-hir.rs:8:29
| |
LL | fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> { LL | fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error: [o, o, o] error: ['a: o, T: o, 'a: o]
--> $DIR/capture-lifetime-not-in-hir.rs:14:30 --> $DIR/capture-lifetime-not-in-hir.rs:14:30
| |
LL | fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a { LL | fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {

View file

@ -10,7 +10,7 @@ note: lifetime declared here
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> { LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {
| ^^ | ^^
error: [o] error: ['a: o]
--> $DIR/implicit-capture-late.rs:10:55 --> $DIR/implicit-capture-late.rs:10:55
| |
LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> { LL | fn foo(x: Vec<i32>) -> Box<dyn for<'a> Deref<Target = impl ?Sized>> {

View file

@ -7,14 +7,16 @@ impl<T> Captures<'_> for T {}
trait Foo<'i> { trait Foo<'i> {
fn implicit_capture_early<'a: 'a>() -> impl Sized {} fn implicit_capture_early<'a: 'a>() -> impl Sized {}
//~^ [o, *, *, o, o] //~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
// Self, 'i, 'a, 'i_duplicated, 'a_duplicated
fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o] fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o] fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o] fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
//~^ [Self: o, 'i: *, 'a: o, 'i: o]
} }
fn main() {} fn main() {}

View file

@ -1,23 +1,23 @@
error: [o, *, *, o, o] error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:9:44 --> $DIR/variance.rs:9:44
| |
LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {} LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o, *, *, o, o] error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:13:44 --> $DIR/variance.rs:12:44
| |
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, *, o, o] error: [Self: o, 'i: *, 'a: o, 'i: o]
--> $DIR/variance.rs:15:48 --> $DIR/variance.rs:15:48
| |
LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o, *, o, o] error: [Self: o, 'i: *, 'a: o, 'i: o]
--> $DIR/variance.rs:17:48 --> $DIR/variance.rs:18:48
| |
LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -1,22 +1,22 @@
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:14:36 --> $DIR/variance.rs:14:36
| |
LL | fn not_captured_early<'a: 'a>() -> impl Sized {} LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32 --> $DIR/variance.rs:19:32
| |
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o] error: ['a: o]
--> $DIR/variance.rs:21:40 --> $DIR/variance.rs:21:40
| |
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o] error: ['a: o]
--> $DIR/variance.rs:26:36 --> $DIR/variance.rs:26:36
| |
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View file

@ -1,22 +1,22 @@
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:14:36 --> $DIR/variance.rs:14:36
| |
LL | fn not_captured_early<'a: 'a>() -> impl Sized {} LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32 --> $DIR/variance.rs:19:32
| |
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o] error: ['a: o]
--> $DIR/variance.rs:21:40 --> $DIR/variance.rs:21:40
| |
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o] error: ['a: o]
--> $DIR/variance.rs:26:36 --> $DIR/variance.rs:26:36
| |
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View file

@ -1,10 +1,10 @@
error: [*] error: ['a: *]
--> $DIR/variance.rs:14:36 --> $DIR/variance.rs:14:36
| |
LL | fn not_captured_early<'a: 'a>() -> impl Sized {} LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32 --> $DIR/variance.rs:19:32
| |
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
@ -16,7 +16,7 @@ error: []
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o] error: ['a: o]
--> $DIR/variance.rs:26:36 --> $DIR/variance.rs:26:36
| |
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View file

@ -12,17 +12,17 @@ trait Captures<'a> {}
impl<T> Captures<'_> for T {} impl<T> Captures<'_> for T {}
fn not_captured_early<'a: 'a>() -> impl Sized {} fn not_captured_early<'a: 'a>() -> impl Sized {}
//[old]~^ [*] //[old]~^ ['a: *]
//[new]~^^ [*, o] //[new]~^^ ['a: *, 'a: o]
//[e2024]~^^^ [*, o] //[e2024]~^^^ ['a: *, 'a: o]
fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [*, o] fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ ['a: *, 'a: o]
fn not_captured_late<'a>(_: &'a ()) -> impl Sized {} fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
//[old]~^ [] //[old]~^ []
//[new]~^^ [o] //[new]~^^ ['a: o]
//[e2024]~^^^ [o] //[e2024]~^^^ ['a: o]
fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o] fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ ['a: o]
fn main() {} fn main() {}

View file

@ -5,21 +5,21 @@
trait Captures<'a> {} trait Captures<'a> {}
impl<T> Captures<'_> for T {} impl<T> Captures<'_> for T {}
type NotCapturedEarly<'a> = impl Sized; //~ [*, o] type NotCapturedEarly<'a> = impl Sized; //~ ['a: *, 'a: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o] type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ ['a: *, 'a: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o] type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ ['a: *, 'b: o, 'a: o]
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
//~| ERROR: unconstrained opaque type //~| ERROR: unconstrained opaque type
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o] type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ ['a: *, 'b: o, 'a: o]
//~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from `dyn` type
//~| ERROR: unconstrained opaque type //~| ERROR: unconstrained opaque type
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o] type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR ['a: *, 'b: *, T: o, 'a: o, 'b: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
trait Foo<'i> { trait Foo<'i> {
@ -31,24 +31,24 @@ trait Foo<'i> {
} }
impl<'i> Foo<'i> for &'i () { impl<'i> Foo<'i> for &'i () {
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o] type ImplicitCapture<'a> = impl Sized; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o] type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o] type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
} }
impl<'i> Foo<'i> for () { impl<'i> Foo<'i> for () {
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o] type ImplicitCapture<'a> = impl Sized; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o] type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o] type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ ['i: *, 'a: *, 'a: o, 'i: o]
//~^ ERROR: unconstrained opaque type //~^ ERROR: unconstrained opaque type
} }
@ -59,15 +59,15 @@ impl<'a> Nesting<'a> for &'a () {
type Output = &'a (); type Output = &'a ();
} }
type NestedDeeply<'a> = type NestedDeeply<'a> =
impl Nesting< //~ [*, o] impl Nesting< //~ ['a: *, 'a: o]
'a, 'a,
Output = impl Nesting< //~ [*, o] Output = impl Nesting< //~ ['a: *, 'a: o]
'a, 'a,
Output = impl Nesting< //~ [*, o] Output = impl Nesting< //~ ['a: *, 'a: o]
'a, 'a,
Output = impl Nesting< //~ [*, o] Output = impl Nesting< //~ ['a: *, 'a: o]
'a, 'a,
Output = impl Nesting<'a> //~ [*, o] Output = impl Nesting<'a> //~ ['a: *, 'a: o]
> >
>, >,
>, >,

View file

@ -110,73 +110,73 @@ LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| |
= note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:8:29 --> $DIR/variance.rs:8:29
| |
LL | type NotCapturedEarly<'a> = impl Sized; LL | type NotCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:11:26 --> $DIR/variance.rs:11:26
| |
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>; LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o, o] error: ['a: *, 'b: o, 'a: o]
--> $DIR/variance.rs:14:56 --> $DIR/variance.rs:14:56
| |
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, o, o] error: ['a: *, 'b: o, 'a: o]
--> $DIR/variance.rs:18:49 --> $DIR/variance.rs:18:49
| |
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o, o] error: ['a: *, 'b: *, T: o, 'a: o, 'b: o]
--> $DIR/variance.rs:22:27 --> $DIR/variance.rs:22:27
| |
LL | type Bar<'a, 'b: 'b, T> = impl Sized; LL | type Bar<'a, 'b: 'b, T> = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, *, o, o] error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:34:32 --> $DIR/variance.rs:34:32
| |
LL | type ImplicitCapture<'a> = impl Sized; LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, *, o, o] error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:37:42 --> $DIR/variance.rs:37:42
| |
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o] error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:40:39 --> $DIR/variance.rs:40:39
| |
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o] error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:45:32 --> $DIR/variance.rs:45:32
| |
LL | type ImplicitCapture<'a> = impl Sized; LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [*, *, o, o] error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:48:42 --> $DIR/variance.rs:48:42
| |
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o] error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:51:39 --> $DIR/variance.rs:51:39
| |
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:62:5 --> $DIR/variance.rs:62:5
| |
LL | / impl Nesting< LL | / impl Nesting<
@ -188,7 +188,7 @@ LL | | >,
LL | | >; LL | | >;
| |_____^ | |_____^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:64:18 --> $DIR/variance.rs:64:18
| |
LL | Output = impl Nesting< LL | Output = impl Nesting<
@ -201,7 +201,7 @@ LL | | >,
LL | | >, LL | | >,
| |_________^ | |_________^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:66:22 --> $DIR/variance.rs:66:22
| |
LL | Output = impl Nesting< LL | Output = impl Nesting<
@ -214,7 +214,7 @@ LL | | >
LL | | >, LL | | >,
| |_____________^ | |_____________^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:68:26 --> $DIR/variance.rs:68:26
| |
LL | Output = impl Nesting< LL | Output = impl Nesting<
@ -224,7 +224,7 @@ LL | | Output = impl Nesting<'a>
LL | | > LL | | >
| |_________________^ | |_________________^
error: [*, o] error: ['a: *, 'a: o]
--> $DIR/variance.rs:70:30 --> $DIR/variance.rs:70:30
| |
LL | Output = impl Nesting<'a> LL | Output = impl Nesting<'a>

View file

@ -10,7 +10,7 @@ trait Trait {
} }
#[rustc_variance] #[rustc_variance]
struct Foo<T: Trait> { //~ ERROR [o] struct Foo<T: Trait> { //~ ERROR [T: o]
field: [u8; <T as Trait>::Const] field: [u8; <T as Trait>::Const]
//~^ ERROR: unconstrained generic constant //~^ ERROR: unconstrained generic constant
} }

View file

@ -9,7 +9,7 @@ help: try adding a `where` bound
LL | struct Foo<T: Trait> where [(); <T as Trait>::Const]: { LL | struct Foo<T: Trait> where [(); <T as Trait>::Const]: {
| ++++++++++++++++++++++++++++++++ | ++++++++++++++++++++++++++++++++
error: [o] error: [T: o]
--> $DIR/variance-associated-consts.rs:13:1 --> $DIR/variance-associated-consts.rs:13:1
| |
LL | struct Foo<T: Trait> { LL | struct Foo<T: Trait> {

View file

@ -10,12 +10,12 @@ trait Trait<'a> {
} }
#[rustc_variance] #[rustc_variance]
struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +] struct Foo<'a, T : Trait<'a>> { //~ ERROR ['a: +, T: +]
field: (T, &'a ()) field: (T, &'a ())
} }
#[rustc_variance] #[rustc_variance]
struct Bar<'a, T : Trait<'a>> { //~ ERROR [o, o] struct Bar<'a, T : Trait<'a>> { //~ ERROR ['a: o, T: o]
field: <T as Trait<'a>>::Type field: <T as Trait<'a>>::Type
} }

View file

@ -1,10 +1,10 @@
error: [+, +] error: ['a: +, T: +]
--> $DIR/variance-associated-types.rs:13:1 --> $DIR/variance-associated-types.rs:13:1
| |
LL | struct Foo<'a, T : Trait<'a>> { LL | struct Foo<'a, T : Trait<'a>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: ['a: o, T: o]
--> $DIR/variance-associated-types.rs:18:1 --> $DIR/variance-associated-types.rs:18:1
| |
LL | struct Bar<'a, T : Trait<'a>> { LL | struct Bar<'a, T : Trait<'a>> {

View file

@ -4,7 +4,7 @@
// For better or worse, associated types are invariant, and hence we // For better or worse, associated types are invariant, and hence we
// get an invariant result for `'a`. // get an invariant result for `'a`.
#[rustc_variance] #[rustc_variance]
struct Foo<'a> { //~ ERROR [o] struct Foo<'a> { //~ ERROR ['a: o]
x: Box<dyn Fn(i32) -> &'a i32 + 'static> x: Box<dyn Fn(i32) -> &'a i32 + 'static>
} }

View file

@ -1,4 +1,4 @@
error: [o] error: ['a: o]
--> $DIR/variance-object-types.rs:7:1 --> $DIR/variance-object-types.rs:7:1
| |
LL | struct Foo<'a> { LL | struct Foo<'a> {

View file

@ -6,7 +6,7 @@
// Regions that just appear in normal spots are contravariant: // Regions that just appear in normal spots are contravariant:
#[rustc_variance] #[rustc_variance]
struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +] struct Test2<'a, 'b, 'c> { //~ ERROR ['a: +, 'b: +, 'c: +]
x: &'a isize, x: &'a isize,
y: &'b [isize], y: &'b [isize],
c: &'c str c: &'c str
@ -15,7 +15,7 @@ struct Test2<'a, 'b, 'c> { //~ ERROR [+, +, +]
// Those same annotations in function arguments become covariant: // Those same annotations in function arguments become covariant:
#[rustc_variance] #[rustc_variance]
struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -] struct Test3<'a, 'b, 'c> { //~ ERROR ['a: -, 'b: -, 'c: -]
x: extern "Rust" fn(&'a isize), x: extern "Rust" fn(&'a isize),
y: extern "Rust" fn(&'b [isize]), y: extern "Rust" fn(&'b [isize]),
c: extern "Rust" fn(&'c str), c: extern "Rust" fn(&'c str),
@ -24,7 +24,7 @@ struct Test3<'a, 'b, 'c> { //~ ERROR [-, -, -]
// Mutability induces invariance: // Mutability induces invariance:
#[rustc_variance] #[rustc_variance]
struct Test4<'a, 'b:'a> { //~ ERROR [+, o] struct Test4<'a, 'b:'a> { //~ ERROR ['a: +, 'b: o]
x: &'a mut &'b isize, x: &'a mut &'b isize,
} }
@ -32,7 +32,7 @@ struct Test4<'a, 'b:'a> { //~ ERROR [+, o]
// contravariant context: // contravariant context:
#[rustc_variance] #[rustc_variance]
struct Test5<'a, 'b:'a> { //~ ERROR [-, o] struct Test5<'a, 'b:'a> { //~ ERROR ['a: -, 'b: o]
x: extern "Rust" fn(&'a mut &'b isize), x: extern "Rust" fn(&'a mut &'b isize),
} }
@ -42,14 +42,14 @@ struct Test5<'a, 'b:'a> { //~ ERROR [-, o]
// argument list occurs in an invariant context. // argument list occurs in an invariant context.
#[rustc_variance] #[rustc_variance]
struct Test6<'a, 'b:'a> { //~ ERROR [+, o] struct Test6<'a, 'b:'a> { //~ ERROR ['a: +, 'b: o]
x: &'a mut extern "Rust" fn(&'b isize), x: &'a mut extern "Rust" fn(&'b isize),
} }
// No uses at all is bivariant: // No uses at all is bivariant:
#[rustc_variance] #[rustc_variance]
struct Test7<'a> { //~ ERROR [*] struct Test7<'a> { //~ ERROR ['a: *]
//~^ ERROR: `'a` is never used //~^ ERROR: `'a` is never used
x: isize x: isize
} }
@ -57,7 +57,7 @@ struct Test7<'a> { //~ ERROR [*]
// Try enums too. // Try enums too.
#[rustc_variance] #[rustc_variance]
enum Test8<'a, 'b, 'c:'b> { //~ ERROR [-, +, o] enum Test8<'a, 'b, 'c:'b> { //~ ERROR ['a: -, 'b: +, 'c: o]
Test8A(extern "Rust" fn(&'a isize)), Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]), Test8B(&'b [isize]),
Test8C(&'b mut &'c str), Test8C(&'b mut &'c str),

View file

@ -6,43 +6,43 @@ LL | struct Test7<'a> {
| |
= help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
error: [+, +, +] error: ['a: +, 'b: +, 'c: +]
--> $DIR/variance-regions-direct.rs:9:1 --> $DIR/variance-regions-direct.rs:9:1
| |
LL | struct Test2<'a, 'b, 'c> { LL | struct Test2<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: [-, -, -] error: ['a: -, 'b: -, 'c: -]
--> $DIR/variance-regions-direct.rs:18:1 --> $DIR/variance-regions-direct.rs:18:1
| |
LL | struct Test3<'a, 'b, 'c> { LL | struct Test3<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o] error: ['a: +, 'b: o]
--> $DIR/variance-regions-direct.rs:27:1 --> $DIR/variance-regions-direct.rs:27:1
| |
LL | struct Test4<'a, 'b:'a> { LL | struct Test4<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: [-, o] error: ['a: -, 'b: o]
--> $DIR/variance-regions-direct.rs:35:1 --> $DIR/variance-regions-direct.rs:35:1
| |
LL | struct Test5<'a, 'b:'a> { LL | struct Test5<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o] error: ['a: +, 'b: o]
--> $DIR/variance-regions-direct.rs:45:1 --> $DIR/variance-regions-direct.rs:45:1
| |
LL | struct Test6<'a, 'b:'a> { LL | struct Test6<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: [*] error: ['a: *]
--> $DIR/variance-regions-direct.rs:52:1 --> $DIR/variance-regions-direct.rs:52:1
| |
LL | struct Test7<'a> { LL | struct Test7<'a> {
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error: [-, +, o] error: ['a: -, 'b: +, 'c: o]
--> $DIR/variance-regions-direct.rs:60:1 --> $DIR/variance-regions-direct.rs:60:1
| |
LL | enum Test8<'a, 'b, 'c:'b> { LL | enum Test8<'a, 'b, 'c:'b> {

View file

@ -5,7 +5,7 @@
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#[rustc_variance] #[rustc_variance]
enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *] enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR ['a: -, 'b: +, 'c: o, 'd: *]
//~^ ERROR: `'d` is never used //~^ ERROR: `'d` is never used
Test8A(extern "Rust" fn(&'a isize)), Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]), Test8B(&'b [isize]),
@ -13,25 +13,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
} }
#[rustc_variance] #[rustc_variance]
struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -] struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR ['w: *, 'x: o, 'y: +, 'z: -]
//~^ ERROR: `'w` is never used //~^ ERROR: `'w` is never used
f: Base<'z, 'y, 'x, 'w> f: Base<'z, 'y, 'x, 'w>
} }
#[rustc_variance] // Combine - and + to yield o #[rustc_variance] // Combine - and + to yield o
struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *] struct Derived2<'a, 'b:'a, 'c> { //~ ERROR ['a: o, 'b: o, 'c: *]
//~^ ERROR: `'c` is never used //~^ ERROR: `'c` is never used
f: Base<'a, 'a, 'b, 'c> f: Base<'a, 'a, 'b, 'c>
} }
#[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here) #[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 ['a: o, 'b: +, 'c: *]
//~^ ERROR: `'c` is never used //~^ ERROR: `'c` is never used
f: Base<'a, 'b, 'a, 'c> f: Base<'a, 'b, 'a, 'c>
} }
#[rustc_variance] // Combine + and * to yield + (just pay attention to 'a here) #[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 ['a: -, 'b: +, 'c: o]
f: Base<'a, 'b, 'c, 'a> f: Base<'a, 'b, 'c, 'a>
} }

View file

@ -30,31 +30,31 @@ LL | struct Derived3<'a:'b, 'b, 'c> {
| |
= help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData` = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
error: [-, +, o, *] error: ['a: -, 'b: +, 'c: o, 'd: *]
--> $DIR/variance-regions-indirect.rs:8:1 --> $DIR/variance-regions-indirect.rs:8:1
| |
LL | enum Base<'a, 'b, 'c:'b, 'd> { LL | enum Base<'a, 'b, 'c:'b, 'd> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o, +, -] error: ['w: *, 'x: o, 'y: +, 'z: -]
--> $DIR/variance-regions-indirect.rs:16:1 --> $DIR/variance-regions-indirect.rs:16:1
| |
LL | struct Derived1<'w, 'x:'y, 'y, 'z> { LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o, *] error: ['a: o, 'b: o, 'c: *]
--> $DIR/variance-regions-indirect.rs:22:1 --> $DIR/variance-regions-indirect.rs:22:1
| |
LL | struct Derived2<'a, 'b:'a, 'c> { LL | struct Derived2<'a, 'b:'a, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, +, *] error: ['a: o, 'b: +, 'c: *]
--> $DIR/variance-regions-indirect.rs:28:1 --> $DIR/variance-regions-indirect.rs:28:1
| |
LL | struct Derived3<'a:'b, 'b, 'c> { LL | struct Derived3<'a:'b, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [-, +, o] error: ['a: -, 'b: +, 'c: o]
--> $DIR/variance-regions-indirect.rs:34:1 --> $DIR/variance-regions-indirect.rs:34:1
| |
LL | struct Derived4<'a, 'b, 'c:'b> { LL | struct Derived4<'a, 'b, 'c:'b> {

View file

@ -13,24 +13,24 @@ trait Setter<T> {
} }
#[rustc_variance] #[rustc_variance]
struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +] struct TestStruct<U,T:Setter<U>> { //~ ERROR [U: +, T: +]
t: T, u: U t: T, u: U
} }
#[rustc_variance] #[rustc_variance]
enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +] enum TestEnum<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used //~^ ERROR: `U` is never used
Foo(T) Foo(T)
} }
#[rustc_variance] #[rustc_variance]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +] struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used //~^ ERROR: `U` is never used
t: T t: T
} }
#[rustc_variance] #[rustc_variance]
struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +] struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used //~^ ERROR: `U` is never used
t: T t: T
} }

View file

@ -25,25 +25,25 @@ LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
= help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData` = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
= help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
error: [+, +] error: [U: +, T: +]
--> $DIR/variance-trait-bounds.rs:16:1 --> $DIR/variance-trait-bounds.rs:16:1
| |
LL | struct TestStruct<U,T:Setter<U>> { LL | struct TestStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +] error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:21:1 --> $DIR/variance-trait-bounds.rs:21:1
| |
LL | enum TestEnum<U,T:Setter<U>> { LL | enum TestEnum<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +] error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:27:1 --> $DIR/variance-trait-bounds.rs:27:1
| |
LL | struct TestContraStruct<U,T:Setter<U>> { LL | struct TestContraStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +] error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:33:1 --> $DIR/variance-trait-bounds.rs:33:1
| |
LL | struct TestBox<U,T:Getter<U>+Setter<U>> { LL | struct TestBox<U,T:Getter<U>+Setter<U>> {

View file

@ -11,7 +11,7 @@ use std::mem;
trait T { fn foo(&self); } trait T { fn foo(&self); }
#[rustc_variance] #[rustc_variance]
struct TOption<'a> { //~ ERROR [+] struct TOption<'a> { //~ ERROR ['a: +]
v: Option<Box<dyn T + 'a>>, v: Option<Box<dyn T + 'a>>,
} }

View file

@ -1,4 +1,4 @@
error: [+] error: ['a: +]
--> $DIR/variance-trait-object-bound.rs:14:1 --> $DIR/variance-trait-object-bound.rs:14:1
| |
LL | struct TOption<'a> { LL | struct TOption<'a> {

View file

@ -4,24 +4,24 @@
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#[rustc_variance] #[rustc_variance]
struct TestImm<A, B> { //~ ERROR [+, +] struct TestImm<A, B> { //~ ERROR [A: +, B: +]
x: A, x: A,
y: B, y: B,
} }
#[rustc_variance] #[rustc_variance]
struct TestMut<A, B:'static> { //~ ERROR [+, o] struct TestMut<A, B:'static> { //~ ERROR [A: +, B: o]
x: A, x: A,
y: &'static mut B, y: &'static mut B,
} }
#[rustc_variance] #[rustc_variance]
struct TestIndirect<A:'static, B:'static> { //~ ERROR [+, o] struct TestIndirect<A:'static, B:'static> { //~ ERROR [A: +, B: o]
m: TestMut<A, B> m: TestMut<A, B>
} }
#[rustc_variance] #[rustc_variance]
struct TestIndirect2<A:'static, B:'static> { //~ ERROR [o, o] struct TestIndirect2<A:'static, B:'static> { //~ ERROR [A: o, B: o]
n: TestMut<A, B>, n: TestMut<A, B>,
m: TestMut<B, A> m: TestMut<B, A>
} }
@ -35,7 +35,7 @@ trait Setter<A> {
} }
#[rustc_variance] #[rustc_variance]
struct TestObject<A, R> { //~ ERROR [o, o] struct TestObject<A, R> { //~ ERROR [A: o, R: o]
n: Box<dyn Setter<A>+Send>, n: Box<dyn Setter<A>+Send>,
m: Box<dyn Getter<R>+Send>, m: Box<dyn Getter<R>+Send>,
} }

View file

@ -1,28 +1,28 @@
error: [+, +] error: [A: +, B: +]
--> $DIR/variance-types-bounds.rs:7:1 --> $DIR/variance-types-bounds.rs:7:1
| |
LL | struct TestImm<A, B> { LL | struct TestImm<A, B> {
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
error: [+, o] error: [A: +, B: o]
--> $DIR/variance-types-bounds.rs:13:1 --> $DIR/variance-types-bounds.rs:13:1
| |
LL | struct TestMut<A, B:'static> { LL | struct TestMut<A, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o] error: [A: +, B: o]
--> $DIR/variance-types-bounds.rs:19:1 --> $DIR/variance-types-bounds.rs:19:1
| |
LL | struct TestIndirect<A:'static, B:'static> { LL | struct TestIndirect<A:'static, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: [A: o, B: o]
--> $DIR/variance-types-bounds.rs:24:1 --> $DIR/variance-types-bounds.rs:24:1
| |
LL | struct TestIndirect2<A:'static, B:'static> { LL | struct TestIndirect2<A:'static, B:'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: [A: o, R: o]
--> $DIR/variance-types-bounds.rs:38:1 --> $DIR/variance-types-bounds.rs:38:1
| |
LL | struct TestObject<A, R> { LL | struct TestObject<A, R> {

View file

@ -7,32 +7,32 @@ use std::cell::Cell;
// not considered bivariant. // not considered bivariant.
#[rustc_variance] #[rustc_variance]
struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR [+, o, o] struct InvariantMut<'a,A:'a,B:'a> { //~ ERROR ['a: +, A: o, B: o]
t: &'a mut (A,B) t: &'a mut (A,B)
} }
#[rustc_variance] #[rustc_variance]
struct InvariantCell<A> { //~ ERROR [o] struct InvariantCell<A> { //~ ERROR [A: o]
t: Cell<A> t: Cell<A>
} }
#[rustc_variance] #[rustc_variance]
struct InvariantIndirect<A> { //~ ERROR [o] struct InvariantIndirect<A> { //~ ERROR [A: o]
t: InvariantCell<A> t: InvariantCell<A>
} }
#[rustc_variance] #[rustc_variance]
struct Covariant<A> { //~ ERROR [+] struct Covariant<A> { //~ ERROR [A: +]
t: A, u: fn() -> A t: A, u: fn() -> A
} }
#[rustc_variance] #[rustc_variance]
struct Contravariant<A> { //~ ERROR [-] struct Contravariant<A> { //~ ERROR [A: -]
t: fn(A) t: fn(A)
} }
#[rustc_variance] #[rustc_variance]
enum Enum<A,B,C> { //~ ERROR [+, -, o] enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o]
Foo(Covariant<A>), Foo(Covariant<A>),
Bar(Contravariant<B>), Bar(Contravariant<B>),
Zed(Covariant<C>,Contravariant<C>) Zed(Covariant<C>,Contravariant<C>)

View file

@ -1,34 +1,34 @@
error: [+, o, o] error: ['a: +, A: o, B: o]
--> $DIR/variance-types.rs:10:1 --> $DIR/variance-types.rs:10:1
| |
LL | struct InvariantMut<'a,A:'a,B:'a> { LL | struct InvariantMut<'a,A:'a,B:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o] error: [A: o]
--> $DIR/variance-types.rs:15:1 --> $DIR/variance-types.rs:15:1
| |
LL | struct InvariantCell<A> { LL | struct InvariantCell<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: [o] error: [A: o]
--> $DIR/variance-types.rs:20:1 --> $DIR/variance-types.rs:20:1
| |
LL | struct InvariantIndirect<A> { LL | struct InvariantIndirect<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [+] error: [A: +]
--> $DIR/variance-types.rs:25:1 --> $DIR/variance-types.rs:25:1
| |
LL | struct Covariant<A> { LL | struct Covariant<A> {
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
error: [-] error: [A: -]
--> $DIR/variance-types.rs:30:1 --> $DIR/variance-types.rs:30:1
| |
LL | struct Contravariant<A> { LL | struct Contravariant<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
error: [+, -, o] error: [A: +, B: -, C: o]
--> $DIR/variance-types.rs:35:1 --> $DIR/variance-types.rs:35:1
| |
LL | enum Enum<A,B,C> { LL | enum Enum<A,B,C> {