What does "note: assuming a 'static lifetime..." mean here?

Hi,
I just stumbled upon a confusing error message and I'm looking for some insight into what it's trying to tell.

This example (playground link)

struct A<'a> {
    inner: &'a i32
}

impl core::ops::Deref for A {
    type Target = i32;
    fn deref(&self) -> &Self::Target{
        &self.inner
    }
}

fn main() {
    let a: A = todo!();
}

Generates the following error:

   Compiling playground v0.0.1 (/playground)
error[E0726]: implicit elided lifetime not allowed here
 --> src/main.rs:5:27
  |
5 | impl core::ops::Deref for A {
  |                           ^ expected lifetime parameter
  |
  = note: assuming a `'static` lifetime...
help: indicate the anonymous lifetime
  |
5 | impl core::ops::Deref for A<'_> {
  |                            ++++

For more information about this error, try `rustc --explain E0726`.
error: could not compile `playground` due to previous error

What does the note "assuming a `'static` lifetime..." mean here? rustc --explain E0726 doesn't help much. The note would make sense to me if it was a warning for some old now-deprecated syntax but since it's an error I don't understand.

To be clear I understand why this doesn't compile, but I'm just confused at what the compiler is trying to tell me.

1 Like

New guy guessing, so I'm open to correction:

I think what it's trying to tell you is that you declared a type with an explicit lifetime, and now you're trying to implement a function for that type, but you didn't mention anything about this lifetime in the new functionality you're implementing. Rust assumes that lifetime doesn't matter, but it doesn't want to compile the program without being sure. If you change your impl core::ops::Deref for A to impl core::ops::Deref for A<'_> then it compiles with a warning about an unused variable.

From my limited understanding in The Book, I read that <'_> as saying 'there is a lifetime associated with the A struct that usually gets determined, but in this case we don't care about it`.

Playground

Yeah, the note seems weird… let’s try to learn more.

…/rust/compiler $ rg "assuming a \`'static\` lifetime..."
rustc_resolve/src/late.rs
1723:                        err.note("assuming a `'static` lifetime...");

alright… that’s here

let’s look what PR introduced it… https://github.com/rust-lang/rust/blame/05e678ccca974a8d0c26991083fb4cf8fff84e74/compiler/rustc_resolve/src/late.rs#L1707-L1725

nope, they just moved it: Separate `AnonymousCreateParameter` and `ReportElidedInPath`. · rust-lang/rust@bf38ba2 · GitHub

Next step… https://github.com/rust-lang/rust/blame/237e267b8050bac6e24d412f0d577c5ca9d57ca1/compiler/rustc_resolve/src/late.rs#L1538-L1571

again, just moved it: https://github.com/rust-lang/rust/commit/a9e13fa5533df7fc004aeab00d45822eacb8461e#diff-512b626e6a7a3f17f9855012f627e59563ad3f2cea54c4b67bf29594fbe29f60L332

Next up… https://github.com/rust-lang/rust/blame/ca57bada05373ff227c661cc542e99c92b70c0ee/compiler/rustc_ast_lowering/src/path.rs#L316-L333

only moved it, again: https://github.com/rust-lang/rust/commit/b6211332001dc670e5e4ceedf4c084146b9a0d41#diff-512b626e6a7a3f17f9855012f627e59563ad3f2cea54c4b67bf29594fbe29f60L327

Now this blame looks promising! https://github.com/rust-lang/rust/blame/5ea7ea8a5786729d3e8d0d513819f52b4d9047dd/compiler/rustc_ast_lowering/src/path.rs#L327

Yup, here’s the addition: https://github.com/rust-lang/rust/commit/ae024919845a44473c22b8c3f1dfa075c9c5c75d#diff-512b626e6a7a3f17f9855012f627e59563ad3f2cea54c4b67bf29594fbe29f60R339, and 1.55 matches with when this appeared: Compiler Explorer

Not let’s look at the PR

https://github.com/rust-lang/rust/pull/87244

To be honest… no, looking through all the test cases among https://github.com/rust-lang/rust/pull/87244/files, I can’t find a single one where the “= note: assuming a `'static` lifetime...” note makes any sense to me.

Or is this to explain potential subsequent error messages because compilation goes on for a bit? Let’s see…

Ah, here’s a relevant test case: https://github.com/rust-lang/rust/pull/87244/files#diff-f44e51dff9919426ca5fbeb1e77c4147931ed1a50c5175f51ca14fdf810a937d

pub trait Trait {}
#[repr(transparent)]
pub struct Wrapper<T: Trait>(T);
#[repr(transparent)]
pub struct Ref<'a>(&'a u8);
impl Trait for Ref {}

extern "C" {
    pub fn repro(_: Wrapper<Ref>);
}

So it looks like the compiler does indeed make the syntactically erroneous impl Trait for Ref still generate a trait implementation, so that additional error messages can be generated, I presume, and for whatever weird reason it does indeed fall back to 'static for that. I mean, it’s weird… and very confusing in terms of error messages. Better than an ICE I suppose (here’s the issue this test case if from: https://github.com/rust-lang/rust/issues/80468), but still… Honestly, it should probably either treat the missing lifetime as elided, or consider the whole trait implementation too syntactically incorrect to consider at all; I don’t see how the status quo would be better than either of that.


Feel free to open an issue on GitHub about this, maybe someone wants to improve the situation. :slight_smile:

https://github.com/rust-lang/rust/issues/new/choose

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.