Help explain this code about the lifetime

Why the error reported here is not the same?

struct MutStr<'a> {
  s: &'a mut &'a str
}

fn test_static_ref() {
    let mut s = "hello";
    let _c :&'static mut &'static str = &mut s;
}

fn main() {
    let mut s = "hello";
    let _c = MutStr { s: &mut s };
}

compile errors:

error[E0597]: `s` does not live long enough
 --> src/main.rs:7:41
  |
7 |     let _c :&'static mut &'static str = &mut s;
  |             -------------------------   ^^^^^^ borrowed value does not live long enough
  |             |
  |             type annotation requires that `s` is borrowed for `'static`
8 | }
  | - `s` dropped here while still borrowed

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

why the let _c = MutStr { s: &mut s }.s; not report any errors?

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ae344f39a9818f5a0ccd46ee642ab3c6

In the main function, the lifetime on the string is shortened to something smaller than 'static, but that can't happen in test_static_ref since you explicitly said that it should be 'static.

&mut s, When expanded, it is &'s mut &'static str, then assigned to MutStr, Because &'a mut T is invariant for T, so the 'a equal 'static, finally the field s for MutStr is equal &'static mut &'static str,

The lifetime is shortened on the let mut s = "hello"; line and not when creating the mutable reference, so there's no problem with invariance. To see this, explicitly require that the lifetime is not shortened:

fn main() {
    let mut s: &'static str = "hello";
    let _c = MutStr { s: &mut s };
}

The above will fail to compile because the compiler isn't allowed to shorten the lifetime on s.

1 Like

Thanks

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.