Print the generic parameter along with the variance in dumps.

This commit is contained in:
Camille GILLOT 2024-08-22 21:07:29 +00:00
parent eff09483c6
commit 5cef88c1f4
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_id::CRATE_DEF_ID;
use rustc_middle::ty::TyCtxt;
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_middle::ty::{GenericArgs, TyCtxt};
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<'_>) {
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
for id in tcx.hir().items() {
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 {
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;
}
let variances = tcx.variances_of(id.owner_id);
tcx.dcx().emit_err(crate::errors::VariancesOf {
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)]
#[rustc_variance]
struct Foo<'a, T> { //~ ERROR [+, o]
struct Foo<'a, T> { //~ ERROR ['a: +, T: o]
t: &'a mut T,
}

View File

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

View File

@ -6,13 +6,13 @@ trait Bar<'a> {
}
fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
//~^ ERROR [o, o]
//~^ ERROR ['a: o, T: o]
// captures both T and 'a invariantly
()
}
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`
// 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
|
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
|
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>> {
| ^^
error: [o]
error: ['a: o]
--> $DIR/implicit-capture-late.rs:10:55
|
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> {
fn implicit_capture_early<'a: 'a>() -> impl Sized {}
//~^ [o, *, *, o, o]
// Self, 'i, 'a, 'i_duplicated, 'a_duplicated
//~^ [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
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() {}

View File

@ -1,23 +1,23 @@
error: [o, *, *, o, o]
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:9:44
|
LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [o, *, *, o, o]
--> $DIR/variance.rs:13:44
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:12:44
|
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
|
LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o, *, o, o]
--> $DIR/variance.rs:17:48
error: [Self: o, 'i: *, 'a: o, 'i: o]
--> $DIR/variance.rs:18:48
|
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
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:21:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:26:36
|
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
|
LL | fn not_captured_early<'a: 'a>() -> impl Sized {}
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:19:32
|
LL | fn captured_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:21:40
|
LL | fn not_captured_late<'a>(_: &'a ()) -> impl Sized {}
| ^^^^^^^^^^
error: [o]
error: ['a: o]
--> $DIR/variance.rs:26:36
|
LL | fn captured_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}

View File

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

View File

@ -12,17 +12,17 @@ trait Captures<'a> {}
impl<T> Captures<'_> for T {}
fn not_captured_early<'a: 'a>() -> impl Sized {}
//[old]~^ [*]
//[new]~^^ [*, o]
//[e2024]~^^^ [*, o]
//[old]~^ ['a: *]
//[new]~^^ ['a: *, 'a: 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 {}
//[old]~^ []
//[new]~^^ [o]
//[e2024]~^^^ [o]
//[new]~^^ ['a: 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() {}

View File

@ -5,21 +5,21 @@
trait Captures<'a> {}
impl<T> Captures<'_> for T {}
type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
type NotCapturedEarly<'a> = impl Sized; //~ ['a: *, 'a: o]
//~^ 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
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: 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: 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
trait Foo<'i> {
@ -31,24 +31,24 @@ trait Foo<'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
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
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
}
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
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
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
}
@ -59,15 +59,15 @@ impl<'a> Nesting<'a> for &'a () {
type Output = &'a ();
}
type NestedDeeply<'a> =
impl Nesting< //~ [*, o]
impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting< //~ [*, o]
Output = impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting< //~ [*, o]
Output = impl Nesting< //~ ['a: *, 'a: o]
'a,
Output = impl Nesting< //~ [*, o]
Output = impl Nesting< //~ ['a: *, 'a: o]
'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
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:8:29
|
LL | type NotCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:11:26
|
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o, o]
error: ['a: *, 'b: o, 'a: o]
--> $DIR/variance.rs:14:56
|
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
|
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
|
LL | type Bar<'a, 'b: 'b, T> = impl Sized;
| ^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:34:32
|
LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:37:42
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:40:39
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:45:32
|
LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:48:42
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, *, o, o]
error: ['i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:51:39
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:62:5
|
LL | / impl Nesting<
@ -188,7 +188,7 @@ LL | | >,
LL | | >;
| |_____^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:64:18
|
LL | Output = impl Nesting<
@ -201,7 +201,7 @@ LL | | >,
LL | | >,
| |_________^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:66:22
|
LL | Output = impl Nesting<
@ -214,7 +214,7 @@ LL | | >
LL | | >,
| |_____________^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:68:26
|
LL | Output = impl Nesting<
@ -224,7 +224,7 @@ LL | | Output = impl Nesting<'a>
LL | | >
| |_________________^
error: [*, o]
error: ['a: *, 'a: o]
--> $DIR/variance.rs:70:30
|
LL | Output = impl Nesting<'a>

View File

@ -10,7 +10,7 @@ trait Trait {
}
#[rustc_variance]
struct Foo<T: Trait> { //~ ERROR [o]
struct Foo<T: Trait> { //~ ERROR [T: o]
field: [u8; <T as Trait>::Const]
//~^ 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]: {
| ++++++++++++++++++++++++++++++++
error: [o]
error: [T: o]
--> $DIR/variance-associated-consts.rs:13:1
|
LL | struct Foo<T: Trait> {

View File

@ -10,12 +10,12 @@ fn method(&'a self) { }
}
#[rustc_variance]
struct Foo<'a, T : Trait<'a>> { //~ ERROR [+, +]
struct Foo<'a, T : Trait<'a>> { //~ ERROR ['a: +, T: +]
field: (T, &'a ())
}
#[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
}

View File

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

View File

@ -4,7 +4,7 @@
// For better or worse, associated types are invariant, and hence we
// get an invariant result for `'a`.
#[rustc_variance]
struct Foo<'a> { //~ ERROR [o]
struct Foo<'a> { //~ ERROR ['a: o]
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
|
LL | struct Foo<'a> {

View File

@ -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 ['a: +, 'b: +, 'c: +]
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 ['a: -, 'b: -, 'c: -]
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 ['a: +, 'b: 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 ['a: -, 'b: o]
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.
#[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),
}
// No uses at all is bivariant:
#[rustc_variance]
struct Test7<'a> { //~ ERROR [*]
struct Test7<'a> { //~ ERROR ['a: *]
//~^ ERROR: `'a` is never used
x: isize
}
@ -57,7 +57,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 ['a: -, 'b: +, 'c: o]
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
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`
error: [+, +, +]
error: ['a: +, 'b: +, 'c: +]
--> $DIR/variance-regions-direct.rs:9:1
|
LL | struct Test2<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: [-, -, -]
error: ['a: -, 'b: -, 'c: -]
--> $DIR/variance-regions-direct.rs:18:1
|
LL | struct Test3<'a, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o]
error: ['a: +, 'b: o]
--> $DIR/variance-regions-direct.rs:27:1
|
LL | struct Test4<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [-, o]
error: ['a: -, 'b: o]
--> $DIR/variance-regions-direct.rs:35:1
|
LL | struct Test5<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [+, o]
error: ['a: +, 'b: o]
--> $DIR/variance-regions-direct.rs:45:1
|
LL | struct Test6<'a, 'b:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [*]
error: ['a: *]
--> $DIR/variance-regions-direct.rs:52:1
|
LL | struct Test7<'a> {
| ^^^^^^^^^^^^^^^^
error: [-, +, o]
error: ['a: -, 'b: +, 'c: o]
--> $DIR/variance-regions-direct.rs:60:1
|
LL | enum Test8<'a, 'b, 'c:'b> {

View File

@ -5,7 +5,7 @@
#![feature(rustc_attrs)]
#[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
Test8A(extern "Rust" fn(&'a isize)),
Test8B(&'b [isize]),
@ -13,25 +13,25 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
}
#[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
f: Base<'z, 'y, 'x, 'w>
}
#[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
f: Base<'a, 'a, 'b, 'c>
}
#[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
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 ['a: -, 'b: +, 'c: o]
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`
error: [-, +, o, *]
error: ['a: -, 'b: +, 'c: o, 'd: *]
--> $DIR/variance-regions-indirect.rs:8:1
|
LL | enum Base<'a, 'b, 'c:'b, 'd> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, o, +, -]
error: ['w: *, 'x: o, 'y: +, 'z: -]
--> $DIR/variance-regions-indirect.rs:16:1
|
LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o, *]
error: ['a: o, 'b: o, 'c: *]
--> $DIR/variance-regions-indirect.rs:22:1
|
LL | struct Derived2<'a, 'b:'a, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, +, *]
error: ['a: o, 'b: +, 'c: *]
--> $DIR/variance-regions-indirect.rs:28:1
|
LL | struct Derived3<'a:'b, 'b, 'c> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [-, +, o]
error: ['a: -, 'b: +, 'c: o]
--> $DIR/variance-regions-indirect.rs:34:1
|
LL | struct Derived4<'a, 'b, 'c:'b> {

View File

@ -13,24 +13,24 @@ trait Setter<T> {
}
#[rustc_variance]
struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +]
struct TestStruct<U,T:Setter<U>> { //~ ERROR [U: +, T: +]
t: T, u: U
}
#[rustc_variance]
enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +]
enum TestEnum<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used
Foo(T)
}
#[rustc_variance]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +]
struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [U: *, T: +]
//~^ ERROR: `U` is never used
t: T
}
#[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
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: 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
|
LL | struct TestStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +]
error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:21:1
|
LL | enum TestEnum<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +]
error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:27:1
|
LL | struct TestContraStruct<U,T:Setter<U>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [*, +]
error: [U: *, T: +]
--> $DIR/variance-trait-bounds.rs:33:1
|
LL | struct TestBox<U,T:Getter<U>+Setter<U>> {

View File

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

View File

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

View File

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

View File

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

View File

@ -7,32 +7,32 @@
// not considered bivariant.
#[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)
}
#[rustc_variance]
struct InvariantCell<A> { //~ ERROR [o]
struct InvariantCell<A> { //~ ERROR [A: o]
t: Cell<A>
}
#[rustc_variance]
struct InvariantIndirect<A> { //~ ERROR [o]
struct InvariantIndirect<A> { //~ ERROR [A: o]
t: InvariantCell<A>
}
#[rustc_variance]
struct Covariant<A> { //~ ERROR [+]
struct Covariant<A> { //~ ERROR [A: +]
t: A, u: fn() -> A
}
#[rustc_variance]
struct Contravariant<A> { //~ ERROR [-]
struct Contravariant<A> { //~ ERROR [A: -]
t: fn(A)
}
#[rustc_variance]
enum Enum<A,B,C> { //~ ERROR [+, -, o]
enum Enum<A,B,C> { //~ ERROR [A: +, B: -, C: o]
Foo(Covariant<A>),
Bar(Contravariant<B>),
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
|
LL | struct InvariantMut<'a,A:'a,B:'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: [A: o]
--> $DIR/variance-types.rs:15:1
|
LL | struct InvariantCell<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [o]
error: [A: o]
--> $DIR/variance-types.rs:20:1
|
LL | struct InvariantIndirect<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: [+]
error: [A: +]
--> $DIR/variance-types.rs:25:1
|
LL | struct Covariant<A> {
| ^^^^^^^^^^^^^^^^^^^
error: [-]
error: [A: -]
--> $DIR/variance-types.rs:30:1
|
LL | struct Contravariant<A> {
| ^^^^^^^^^^^^^^^^^^^^^^^
error: [+, -, o]
error: [A: +, B: -, C: o]
--> $DIR/variance-types.rs:35:1
|
LL | enum Enum<A,B,C> {