Lifetime and returned mutable reference

Hi everyone.
I need a method that returns a mutable reference to a field of a struct. However, the compiler gives me this error:

lifetime may not live long enough requirement occurs because of a mutable reference to ``tui_textarea::TextArea<'_>`` mutable references are invariant over their type parameter see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

// works fine
pub fn get_name_input(&self) -> &TextArea<'_> {
    &self.name_input.name_area
}
// not allowed
pub fn get_name_input_as_mut(&mut self) -> &mut TextArea<'_> {
    &mut self.name_input.name_area
}

Why for immutable references it works fine, but not for mutable ones?

The lifetime elision rules say that if you don’t specify a lifetime name in the return type, you get the lifetime of the self borrow if there is one. So, your two functions are actually:

pub fn get_name_input<'x>(&'x self) -> &'x TextArea<'x> {...
pub fn get_name_input_as_mut<'x>(&'x mut self) -> &'x mut TextArea<'x> {...

In both cases, this is not ideal, but in the second it fails entirely because &'a mut Something<'a> is nearly always useless.

Both function signatures should instead be specifying the correct named lifetime for the TextArea — you haven't given enough code context to see what that is, but it will look something like:

impl<'a> YourType<'a> {
    pub fn get_name_input(&self) -> &TextArea<'a> {...
    pub fn get_name_input_as_mut(&mut self) -> &mut TextArea<'a> {...
}

If you have currently written impl YourType<'_>, then you need to change it to give a name to the lifetime instead, as in the above.

3 Likes

I think you meant &'x self.

Whoops. Fixed. (…dot your ‘i’s and cross your 'lts…)

3 Likes

Thank you