Clippy tells me that the lifetimes can be elided, but I'm not sure if they are exactly equivalent

pub struct Wrapper<'a> {
    internal: HashMap<&'a str, u32>,
}

impl<'a> Wrapper<'a> {
    pub fn get(&self, key: &'_ str) -> Option<&'_ u32> {
        self.internal.get(key)
    }
}

Clippy tells me that 'a can be elided, which would turn the code above into:


pub struct Wrapper<'a> {
    internal: HashMap<&'a str, u32>,
}

impl Wrapper<'_> {
    pub fn get(&self, key: &'_ str) -> Option<&'_ u32> {
        self.internal.get(key)
    }
}

So, does the lifetime of the key argument in the get method still refer to the self argument?

It didn't refer to self in the first place. Every input argument with anonymous lifetime gets its own lifetime, any dependency must be explicit.

3 Likes

As far as I know, the lifetimes in your get method are inferred in both cases as:

pub fn get< 'self, 'key>(&'self self, key: &'key str) -> Option<&'self u32> {
  // ...
}

There is no restriction on the 'self lifetime other than that Self must outlive it.

I found rust-analyzer's inlay lifetimeElisionHints quite useful to develop a feeling for what's happening internally:

2 Likes

It's not related to the lifetime in Self before or after the Clippy suggestion.

The two forms are equivalent as you never used 'a except in the header, i.e. not in the get method.

You don't need '_ in the get method either. They're the same as complete elision in this case.

Check out the documentation here. Note that lifetimes that are introduced in a larger scope than the functions -- like a lifetimes within the Self type -- are never candidates for elided parameters.