Confusing E0277 diagnostic with blanket implementations · Issue #119983 · rust-lang/rust (original) (raw)

Code

trait A {} trait B {} impl A for T where T: B {} fn f(_: T) where T: A {} fn g() { f(()) }

Current output

error[E0277]: the trait bound (): B is not satisfied --> :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 --> :3:9 | 3 | impl A for T where T: B {} | ^ ^ - unsatisfied trait bound introduced here note: required by a bound in f --> :4:24 | 4 | fn f(_: T) where T: A {} | ^ required by this bound in f

Desired output

error[E0277]: the trait bound (): A is not satisfied --> :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 --> :4:24 | 4 | fn f(_: T) where T: A {} | ^ required by this bound in f note: an implementation of B for () would also satisfy this bound --> :3:9 | 3 | impl 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