-
Notifications
You must be signed in to change notification settings - Fork 14k
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 hereRationale 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.2Anything else?
No response