Skip to content

#[diagnostic::on_unimplemented] fails to trigger when certain impls are present #130563

Open
@joshlf

Description

@joshlf

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 google/zerocopy#1296, google/zerocopy#1682

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-diagnostic-infraDiagnostics: Issues that affect all diagnostics, or relate to the diagnostic machinery itself.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions