Skip to content

Confusing lifetime diagnostics for trait impl #115903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
eduardosm opened this issue Sep 16, 2023 · 3 comments
Open

Confusing lifetime diagnostics for trait impl #115903

eduardosm opened this issue Sep 16, 2023 · 3 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@eduardosm
Copy link
Contributor

eduardosm commented Sep 16, 2023

Code

trait Tr {
    fn func(x: &u8, y: &u16) -> !;
}

impl Tr for () {
    fn func(_x: &u8, _y: &'static u16) -> ! {
        unimplemented!();
    }
}

Current output

error[E0308]: method not compatible with trait
 --> lib.rs:6:5
  |
6 |     fn func(_x: &u8, _y: &'static u16) -> ! {
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
  |
  = note: expected signature `fn(&u8, &u16) -> _`
             found signature `fn(&u8, &'static u16) -> _`
note: the anonymous lifetime as defined here...
 --> lib.rs:6:17
  |
6 |     fn func(_x: &u8, _y: &'static u16) -> ! {
  |                 ^
  = note: ...does not necessarily outlive the static lifetime

Desired output

No response

Rationale and extra context

The lifetime mismatch occurs because for y, the lifetime of the trait (anonymous) will not outlive the lifetime of the impl ('static). However, the diagnosis is making reference to (the lifetime of?) x, which does not have anything to do with the mismatch.

If I define an explicit lifetime for x in the impl fn:

note: the anonymous lifetime as defined here...
 --> lib.rs:6:5
  |
6 |     fn func<'a>(_x: &'a u8, _y: &'static u16) -> ! {
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...does not necessarily outlive the static lifetime

It refers to some anonymouse lifetime using the span of the whole impl function signature.

Something similar happens if I remove the x argument (from both trait and impl):

note: the anonymous lifetime as defined here...
 --> lib.rs:6:5
  |
6 |     fn func(_y: &'static u16) -> ! {
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...does not necessarily outlive the static lifetime

Other cases

No response

Anything else?

I think the issue might be in the msg_span_from_named_region function from compiler/rustc_infer/src/infer/error_reporting/mod.rs:

ty::BoundRegionKind::BrNamed(_, name) => {
let span = if let Some(param) =
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
{
param.span
} else {
tcx.def_span(scope)
};
let text = if name == kw::UnderscoreLifetime {
"the anonymous lifetime as defined here".to_string()
} else {
format!("the lifetime `{name}` as defined here")
};
(text, Some(span))
}

In this case, name is kw::UnderscoreLifetime and generics.get_named(name) will find the span of the first anonymous lifetime. If there is none, it will fallback to the span of scope (the whole function signature).

@eduardosm eduardosm added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 16, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Sep 16, 2023
@saethlin saethlin added D-confusing Diagnostics: Confusing error or lint that should be reworked. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Sep 17, 2023
@eopb
Copy link
Contributor

eopb commented Sep 19, 2023

@rustbot claim

@eopb
Copy link
Contributor

eopb commented Sep 19, 2023

@rustbot release-assignment

@veera-sivarajan
Copy link
Contributor

Output on rustc 1.79.0:

error[E0308]: method not compatible with trait
 --> <source>:6:5
  |
6 |     fn func(_x: &u8, _y: &'static u16) -> ! {
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
  |
  = note: expected signature `fn(&_, &_) -> _`
             found signature `fn(&_, &'static _) -> _`
note: the anonymous lifetime defined here...
 --> <source>:2:24
  |
2 |     fn func(x: &u8, y: &u16) -> !;
  |                        ^^^^
  = note: ...does not necessarily outlive the static lifetime

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants