Skip to content

Commit

Permalink
Rollup merge of rust-lang#119389 - estebank:issue-116925, r=TaKO8Ki
Browse files Browse the repository at this point in the history
Provide more context on recursive `impl` evaluation overflow

When an associated type `Self::Assoc` is part of a `where` clause, we end up unable to evaluate the requirement and emit a E0275.

We now point at the associated type if specified in the `impl`. If so, we also suggest using that type instead of `Self::Assoc`. Otherwise, we explain that these are not allowed.

```
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
  --> $DIR/impl-wf-cycle-1.rs:15:1
   |
LL | / impl<T: Grault> Grault for (T,)
LL | |
LL | | where
LL | |     Self::A: Baz,
LL | |     Self::B: Fiz,
   | |_________________^
LL |   {
LL |       type A = ();
   |       ------ associated type `<(T,) as Grault>::A` is specified here
   |
note: required for `(T,)` to implement `Grault`
  --> $DIR/impl-wf-cycle-1.rs:15:17
   |
LL | impl<T: Grault> Grault for (T,)
   |                 ^^^^^^     ^^^^
...
LL |     Self::A: Baz,
   |              --- unsatisfied trait bound introduced here
   = note: 1 redundant requirement hidden
   = note: required for `(T,)` to implement `Grault`
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
   |
LL -     Self::A: Baz,
   |
```
```
error[E0275]: overflow evaluating the requirement `<T as B>::Type == <T as B>::Type`
  --> $DIR/impl-wf-cycle-3.rs:7:1
   |
LL | / impl<T> B for T
LL | | where
LL | |     T: A<Self::Type>,
   | |_____________________^
LL |   {
LL |       type Type = bool;
   |       --------- associated type `<T as B>::Type` is specified here
   |
note: required for `T` to implement `B`
  --> $DIR/impl-wf-cycle-3.rs:7:9
   |
LL | impl<T> B for T
   |         ^     ^
LL | where
LL |     T: A<Self::Type>,
   |        ------------- unsatisfied trait bound introduced here
help: replace the associated type with the type specified in this `impl`
   |
LL |     T: A<bool>,
   |          ~~~~
```
```
error[E0275]: overflow evaluating the requirement `<T as Filter>::ToMatch == <T as Filter>::ToMatch`
  --> $DIR/impl-wf-cycle-4.rs:5:1
   |
LL | / impl<T> Filter for T
LL | | where
LL | |     T: Fn(Self::ToMatch),
   | |_________________________^
   |
note: required for `T` to implement `Filter`
  --> $DIR/impl-wf-cycle-4.rs:5:9
   |
LL | impl<T> Filter for T
   |         ^^^^^^     ^
LL | where
LL |     T: Fn(Self::ToMatch),
   |        ----------------- unsatisfied trait bound introduced here
note: associated types for the current `impl` cannot be restricted in `where` clauses
  --> $DIR/impl-wf-cycle-4.rs:7:11
   |
LL |     T: Fn(Self::ToMatch),
   |           ^^^^^^^^^^^^^
```

Fix rust-lang#116925
  • Loading branch information
matthiaskrgr authored Jan 25, 2024
2 parents 8c6cf3c + 29bdf9e commit fd92d88
Show file tree
Hide file tree
Showing 13 changed files with 474 additions and 45 deletions.
240 changes: 195 additions & 45 deletions compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-1.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ LL | | where
LL | | Self::A: Baz,
LL | | Self::B: Fiz,
| |_________________^
LL | {
LL | type A = ();
| ------ associated type `<(T,) as Grault>::A` is specified here
|
note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-1.rs:15:17
Expand All @@ -18,6 +21,10 @@ LL | Self::A: Baz,
| --- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `(T,)` to implement `Grault`
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
|
LL - Self::A: Baz,
|

error: aborting due to 1 previous error

Expand Down
8 changes: 8 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ LL | |
LL | | where
LL | | Self::A: Copy,
| |__________________^
LL | {
LL | type A = ();
| ------ associated type `<(T,) as Grault>::A` is specified here
|
note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-2.rs:7:17
Expand All @@ -15,6 +18,11 @@ LL | impl<T: Grault> Grault for (T,)
...
LL | Self::A: Copy,
| ---- unsatisfied trait bound introduced here
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
|
LL - where
LL - Self::A: Copy,
|

error: aborting due to 1 previous error

Expand Down
13 changes: 13 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
trait A<T> {}

trait B {
type Type;
}

impl<T> B for T //~ ERROR overflow evaluating the requirement
where
T: A<Self::Type>,
{
type Type = bool;
}
fn main() {}
27 changes: 27 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-3.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0275]: overflow evaluating the requirement `<T as B>::Type == <T as B>::Type`
--> $DIR/impl-wf-cycle-3.rs:7:1
|
LL | / impl<T> B for T
LL | | where
LL | | T: A<Self::Type>,
| |_____________________^
LL | {
LL | type Type = bool;
| --------- associated type `<T as B>::Type` is specified here
|
note: required for `T` to implement `B`
--> $DIR/impl-wf-cycle-3.rs:7:9
|
LL | impl<T> B for T
| ^ ^
LL | where
LL | T: A<Self::Type>,
| ------------- unsatisfied trait bound introduced here
help: replace the associated type with the type specified in this `impl`
|
LL | T: A<bool>,
| ~~~~

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
15 changes: 15 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-4.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
trait Filter {
type ToMatch;
}

impl<T> Filter for T //~ ERROR overflow evaluating the requirement
where
T: Fn(Self::ToMatch),
{
}

struct JustFilter<F: Filter> {
filter: F,
}

fn main() {}
25 changes: 25 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-4.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
error[E0275]: overflow evaluating the requirement `<T as Filter>::ToMatch == <T as Filter>::ToMatch`
--> $DIR/impl-wf-cycle-4.rs:5:1
|
LL | / impl<T> Filter for T
LL | | where
LL | | T: Fn(Self::ToMatch),
| |_________________________^
|
note: required for `T` to implement `Filter`
--> $DIR/impl-wf-cycle-4.rs:5:9
|
LL | impl<T> Filter for T
| ^^^^^^ ^
LL | where
LL | T: Fn(Self::ToMatch),
| ----------------- unsatisfied trait bound introduced here
note: associated types for the current `impl` cannot be restricted in `where` clauses
--> $DIR/impl-wf-cycle-4.rs:7:11
|
LL | T: Fn(Self::ToMatch),
| ^^^^^^^^^^^^^

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
31 changes: 31 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-5.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// run-rustfix

trait Baz {}
impl Baz for () {}
impl<T> Baz for (T,) {}

trait Fiz {}
impl Fiz for bool {}

trait Grault {
type A;
type B;
}

impl Grault for () {
type A = ();
type B = bool;
}

impl<T> Grault for (T,)
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
where
T: Grault,
{
type A = ();
type B = bool;
}

fn main() {
let _: <((),) as Grault>::A = ();
}
32 changes: 32 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-5.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// run-rustfix

trait Baz {}
impl Baz for () {}
impl<T> Baz for (T,) {}

trait Fiz {}
impl Fiz for bool {}

trait Grault {
type A;
type B;
}

impl Grault for () {
type A = ();
type B = bool;
}

impl<T> Grault for (T,)
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
where
T: Grault,
Self::A: Baz,
{
type A = ();
type B = bool;
}

fn main() {
let _: <((),) as Grault>::A = ();
}
31 changes: 31 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-5.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-5.rs:20:1
|
LL | / impl<T> Grault for (T,)
LL | |
LL | | where
LL | | T: Grault,
LL | | Self::A: Baz,
| |_________________^
LL | {
LL | type A = ();
| ------ associated type `<(T,) as Grault>::A` is specified here
|
note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-5.rs:20:9
|
LL | impl<T> Grault for (T,)
| ^^^^^^ ^^^^
...
LL | Self::A: Baz,
| --- unsatisfied trait bound introduced here
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
|
LL - T: Grault,
LL - Self::A: Baz,
LL + T: Grault,
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.
30 changes: 30 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-6.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// run-rustfix

trait Baz {}
impl Baz for () {}
impl<T> Baz for (T,) {}

trait Fiz {}
impl Fiz for bool {}

trait Grault {
type A;
type B;
}

impl Grault for () {
type A = ();
type B = bool;
}

impl<T: Grault> Grault for (T,)
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`

{
type A = ();
type B = bool;
}

fn main() {
let _: <((),) as Grault>::A = ();
}
31 changes: 31 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-6.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// run-rustfix

trait Baz {}
impl Baz for () {}
impl<T> Baz for (T,) {}

trait Fiz {}
impl Fiz for bool {}

trait Grault {
type A;
type B;
}

impl Grault for () {
type A = ();
type B = bool;
}

impl<T: Grault> Grault for (T,)
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
where
Self::A: Baz,
{
type A = ();
type B = bool;
}

fn main() {
let _: <((),) as Grault>::A = ();
}
29 changes: 29 additions & 0 deletions tests/ui/associated-types/impl-wf-cycle-6.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
--> $DIR/impl-wf-cycle-6.rs:20:1
|
LL | / impl<T: Grault> Grault for (T,)
LL | |
LL | | where
LL | | Self::A: Baz,
| |_________________^
LL | {
LL | type A = ();
| ------ associated type `<(T,) as Grault>::A` is specified here
|
note: required for `(T,)` to implement `Grault`
--> $DIR/impl-wf-cycle-6.rs:20:17
|
LL | impl<T: Grault> Grault for (T,)
| ^^^^^^ ^^^^
...
LL | Self::A: Baz,
| --- unsatisfied trait bound introduced here
help: associated type for the current `impl` cannot be restricted in `where` clauses, remove this bound
|
LL - where
LL - Self::A: Baz,
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0275`.

0 comments on commit fd92d88

Please sign in to comment.