Description
Code
trait A {}
trait B {}
impl<T> A for T where T: B {}
fn f<T>(_: T) where T: A {}
fn g() { f(()) }
Current output
error[E0277]: the trait bound `(): B` is not satisfied
--> <source>:5:12
|
5 | fn g() { f(()) }
| - ^^ the trait `B` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required for `()` to implement `A`
--> <source>:3:9
|
3 | impl<T> A for T where T: B {}
| ^ ^ - unsatisfied trait bound introduced here
note: required by a bound in `f`
--> <source>:4:24
|
4 | fn f<T>(_: T) where T: A {}
| ^ required by this bound in `f`
Desired output
error[E0277]: the trait bound `(): A` is not satisfied
--> <source>:5:12
|
5 | fn g() { f(()) }
| - ^^ the trait `A` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required by a bound in `f`
--> <source>:4:24
|
4 | fn f<T>(_: T) where T: A {}
| ^ required by this bound in `f`
note: an implementation of `B` for `()` would also satisfy this bound
--> <source>:3:9
|
3 | impl<T> A for T where T: B {}
| ^ ^ - blanket implementation defined here
Rationale and extra context
impl A for () {}
and impl B for () {}
are both valid solutions, but the diagnostic focuses only on the latter. A suggestion to implement A
is arguably easier to understand, as it directly implements the trait that the bound on f
requires, rather than indirectly. In fact, given no knowledge about the intended semantics for A
and B
, for any given type T
, impl B for T {}
is less likely to be correct than impl A for T {}
, since B
may pose additional informal (e.g. safety, documented invariants) requirements on top of those posed by A
.
In my experience this often comes up when using bytemuck, which defines impl<T: Pod> AnyBitPattern for T
.
I understand that the current diagnostic is helpful when the bound is T: Into<U>
or T: TryInto<U>
and the compiler better suggest to implement From
or TryFrom
. Perhaps these traits could be annotated with an attribute, which would then also emit a warning when implementing Into
and TryInto
non-blanketly.
Other cases
No response
Rust Version
rustc 1.73.0 (cc66ad468 2023-10-03)
binary: rustc
commit-hash: cc66ad468955717ab92600c770da8c1601a4ff33
commit-date: 2023-10-03
host: x86_64-unknown-linux-gnu
release: 1.73.0
LLVM version: 17.0.2
Anything else?
No response