Lifetime issue in struct

#[derive(Debug)]
struct NumRef<'a> {
    x: &'a i32,
}

#[derive(Debug)]
struct NumRefMut<'a> {
    x: &'a mut i32,
}

impl<'a> NumRef<'a> {
    fn as_i32_ref(&'a self) -> &'a i32 {
        self.x
    }
}

impl<'a> NumRefMut<'a> {
    fn as_i32_ref(&'a mut self) -> &'a mut i32 {
        self.x
    }
}

fn main() {
    let mut x: i32 = 99;
    let mut y: i32 = 99;
    let mut x_num_ref = NumRef { x: &x };
    let mut y_num_ref = NumRefMut { x: &mut y };
    let x_i32_ref = x_num_ref.as_i32_ref();
    let y_i32_ref = y_num_ref.as_i32_ref();
    let _ = &mut x_num_ref; //L1
    // let _ = &y_num_ref;  //L2
}

I’m a rust beginner, this code succeeds to compile. If uncomment line L2, there is an error , because y_i32_ref continues to mutable borrow y_num_ref even if y_i32_ref is not used . But line L1 has no problem? I think x_i32_ref should borrow x_num_ref as y_i32_ref. Could anyone explain

This error is due to excessive reuse of lifetimes. Do not reuse the ’a lifetime in as_i32_ref:

impl<'a> NumRefMut<'a> {
    fn as_i32_ref<'b>(&'b mut self) -> &'b mut i32 {
        self.x
    }
}

which is short-hand for not specifying any lifetime at all:

// above is the same as this
impl<'a> NumRefMut<'a> {
    fn as_i32_ref(&mut self) -> &mut i32 {
        self.x
    }
}
1 Like

This code is only to understand lifetime. If use ā€˜a in as_i32_ref function signature on purpose, why line L1 L2 behave differently?

Because you borrow mutably forever:

3 Likes

why doesn y_i32_ref borrows forever, but x_i32_ref not ?

It's because when you have nested references, the compiler will automatically convert &'short &'long T into &'short &short T, but it will not make that conversion for mutable references. The two kinds of references are not treated the same.

4 Likes

Let's don't waste the excellent explanation here. It was an answer to the same question I asked earlier.

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.