Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Print the generic parameter along with the variance in dumps. #129429

Merged
merged 1 commit into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading