`#[diagnostic::on_unimplemented]` fails to trigger when certain impls are present
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Consider the following code:
#[diagnostic::on_unimplemented(note = "A custom Foo message!")]
trait Foo {}
#[diagnostic::on_unimplemented(note = "A custom Bar message!")]
trait Bar {}
impl<'a, T> Bar for &'a T {}
fn takes_foo<T: Foo>(_t: T) {}
fn takes_bar<T: Bar>(_t: T) {}
fn main() {
takes_foo(());
takes_bar(());
}
I would expect the #[diagnostic::on_unimplemented] note to be present in the error output for both calls in main. However, what I get instead is:
error[E0277]: the trait bound `(): Foo` is not satisfied
--> src/main.rs:13:15
|
13 | takes_foo(());
| --------- ^^ the trait `Foo` is not implemented for `()`
| |
| required by a bound introduced by this call
|
= note: A custom Foo message!
help: this trait has no implementations, consider adding one
--> src/main.rs:2:1
|
2 | trait Foo {}
| ^^^^^^^^^
note: required by a bound in `takes_foo`
--> src/main.rs:9:17
|
9 | fn takes_foo<T: Foo>(_t: T) {}
| ^^^ required by this bound in `takes_foo`
error[E0277]: the trait bound `(): Bar` is not satisfied
--> src/main.rs:14:15
|
14 | takes_bar(());
| --------- ^^ the trait `Bar` is not implemented for `()`
| |
| required by a bound introduced by this call
|
note: required by a bound in `takes_bar`
--> src/main.rs:10:17
|
10 | fn takes_bar<T: Bar>(_t: T) {}
| ^^^ required by this bound in `takes_bar`
help: consider borrowing here
|
14 | takes_bar(&());
| +
While the custom note is emitted for Foo, it's not for Bar. The culprit seems to be the impl of Bar for &T, which leads rustc down the wrong path and has it suggest only that borrowing is an option. However, that's not always the right suggestion.
cc https://github.com/google/zerocopy/issues/1296, https://github.com/google/zerocopy/pull/1682
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reduced Rust program in the issue and trace rustc's handling of #[diagnostic::on_unimplemented] when the Bar implementation for &T is present. Compare the diagnostics for Foo and Bar; done means the Bar error includes its custom note and does not incorrectly prioritize the borrowing suggestion.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100