Use supertrait as the suggested bound for a blanket impl instead of the bounds from a different blanket impl · Issue #118415 · rust-lang/rust (original) (raw)
Code
trait A: B { fn a(); }
trait B { fn b(); }
trait C {}
impl B for T where T: C, { fn b() {} }
impl A for T { fn a(){ Self::b(); } }
Current output
error[E0277]: the trait bound T: C
is not satisfied
--> src/main.rs🔞15
|
18 | impl A for T {
| ^ the trait C
is not implemented for T
|
note: required for T
to implement B
--> src/main.rs:11:9
|
11 | impl B for T
| ^ ^
12 | where
13 | T: C,
| - unsatisfied trait bound introduced here
note: required by a bound in A
--> src/main.rs:1:10
|
1 | trait A: B {
| ^ required by this bound in A
help: consider restricting type parameter T
|
18 | impl<T: C> A for T {
| +++
For more information about this error, try rustc --explain E0277
.
Desired output
error[E0277]: the trait bound T: B
is not satisfied
--> src/main.rs🔞15
|
18 | impl A for T {
| ^ the trait B
is not implemented for T
|
note: required by a bound in A
--> src/main.rs:1:10
|
1 | trait A: B {
| ^ required by this bound in A
help: consider restricting type parameter T
|
18 | impl<T: B> A for T {
| +++
For more information about this error, try rustc --explain E0277
.
Rationale and extra context
When providing a blanket impl for some trait A
with a supertrait B
, and B
also has a blanket impl bounded on some other trait C
, rustc will suggest bounding A
's blanket impl on C
rather than the supertrait B
. This is a little confusing and likely the incorrect bound to suggest, as it would cause types that directly implement B
to not satisfy the blanket impl for A
, like the following example:
...
impl<T: C> A for T { fn a(){ Self::b(); } }
struct D;
impl C for D {}
struct E;
impl B for E { fn b() {} }
pub fn main() {
D::a();
E::a(); // error: method cannot be called on E
due to unsatisfied trait bounds
}
This works as expected if T: B
is specified as the bound for the blanket impl on A
instead.
Other cases
No response
Anything else?
No response