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/
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?

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


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.