Skip to content

Commit

Permalink
Rollup merge of #129429 - cjgillot:named-variance, r=compiler-errors
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tgross35 authored Aug 25, 2024
2 parents 198a68d + 5cef88c commit 2269381
Show file tree
Hide file tree
Showing 32 changed files with 158 additions and 140 deletions.
32 changes: 24 additions & 8 deletions compiler/rustc_hir_analysis/src/variance/dump.rs
Original file line number Diff line number Diff line change
@@ -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),
});
}
}
Expand All @@ -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),
});
}
}
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0208.rs
Original file line number Diff line number Diff line change
@@ -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,
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0208.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: [+, o]
error: ['a: +, T: o]
--> $DIR/E0208.rs:4:1
|
LL | struct Foo<'a, T> {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/capture-lifetime-not-in-hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`
()
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/implicit-capture-late.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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>> {
Expand Down
12 changes: 7 additions & 5 deletions tests/ui/impl-trait/in-trait/variance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
12 changes: 6 additions & 6 deletions tests/ui/impl-trait/in-trait/variance.stderr
Original file line number Diff line number Diff line change
@@ -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> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/impl-trait/variance.e2024.stderr
Original file line number Diff line number Diff line change
@@ -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> {}
Expand Down
8 changes: 4 additions & 4 deletions tests/ui/impl-trait/variance.new.stderr
Original file line number Diff line number Diff line change
@@ -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> {}
Expand Down
6 changes: 3 additions & 3 deletions tests/ui/impl-trait/variance.old.stderr
Original file line number Diff line number Diff line change
@@ -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> {}
Expand All @@ -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> {}
Expand Down
14 changes: 7 additions & 7 deletions tests/ui/impl-trait/variance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
32 changes: 16 additions & 16 deletions tests/ui/type-alias-impl-trait/variance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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> {
Expand All @@ -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
}

Expand All @@ -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]
>
>,
>,
Expand Down
Loading

0 comments on commit 2269381

Please sign in to comment.