Print the generic parameter along with the variance in dumps.
This commit is contained in:
parent
eff09483c6
commit
5cef88c1f4
@ -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),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: [+, o]
|
||||
error: ['a: +, T: o]
|
||||
--> $DIR/E0208.rs:4:1
|
||||
|
|
||||
LL | struct Foo<'a, T> {
|
||||
|
@ -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`
|
||||
()
|
||||
|
@ -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 {
|
||||
|
@ -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>> {
|
||||
|
@ -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() {}
|
||||
|
@ -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> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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> {}
|
||||
|
@ -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> {}
|
||||
|
@ -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> {}
|
||||
|
@ -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() {}
|
||||
|
@ -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]
|
||||
>
|
||||
>,
|
||||
>,
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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>> {
|
||||
|
@ -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>
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: [o]
|
||||
error: ['a: o]
|
||||
--> $DIR/variance-object-types.rs:7:1
|
||||
|
|
||||
LL | struct Foo<'a> {
|
||||
|
@ -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),
|
||||
|
@ -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> {
|
||||
|
@ -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>
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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>> {
|
||||
|
@ -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>>,
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: [+]
|
||||
error: ['a: +]
|
||||
--> $DIR/variance-trait-object-bound.rs:14:1
|
||||
|
|
||||
LL | struct TOption<'a> {
|
||||
|
@ -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>,
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -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>)
|
||||
|
@ -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> {
|
||||
|
Loading…
Reference in New Issue
Block a user