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