Skip to content

Commit

Permalink
Provide more context on recursive impl evaluation overflow
Browse files Browse the repository at this point in the history
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,
LL +     ,
   |
```
```
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
estebank committed Dec 28, 2023
1 parent a861c89 commit e1381ba
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 47 deletions.
204 changes: 157 additions & 47 deletions compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Large diffs are not rendered by default.

8 changes: 8 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,11 @@ 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,
LL + ,
|

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 - Self::A: Copy,
LL + ,
|

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`.

0 comments on commit e1381ba

Please sign in to comment.