Skip to content

Commit

Permalink
Print the generic parameter along with the variance in dumps.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Aug 22, 2024
1 parent a32d4a0 commit 62b29bb
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]
error: [Self: o, 'i: *, 'a: *, 'a: o, 'i: o]
--> $DIR/variance.rs:13:44
|
LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^

error: [o, *, o, o]
--> $DIR/variance.rs:15:48
error: [Self: o, 'i: *, 'a: o, 'i: o]
--> $DIR/variance.rs:16: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:19: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 62b29bb

Please sign in to comment.