Lifetime of string literal and lifetimes invariance

54 Views Asked by At

I have the following code:

fn foo<'a>(s1: &mut &'a str, s2: &'a str) {
   *s1 = s2
}

let mut x: &'static str = "Hello";
let y = String::from("World");

foo(&mut x, &y);

There is a compiler error at the last line of code:

error[E0597]: y does not live long enough

As I understand it, this happens because both arguments references in the function signature have the same lifetime specified, and the compiler interprets the lifetime of the second argument reference as 'static automatically, but its referent actual lifetime is not static.

Also, as I know, the string literals have the 'static lifetime by default, and, for me, this means that it doesn't matter if I specify an explicit &'static str type for string literal or not.

But, in my example, if I remove the explicit type (&'static str) for x, this code will compile ok.

1

There are 1 best solutions below

1
cafce25 On

You state "Also, as I know, the string literals have the 'static lifetime by default, and, for me, this means that it doesn't matter if I specify an explicit &'static str type for string literal or not." but there is a subtle difference.

When you specify the type of x with it's lifetime, the compiler can't chose any other lifetime for x.

When you don't specify the lifetime the compiler is free to pick any lifetime, it can shorten the 'static lifetime of the string literal1 so that the lifetime in x fit's the lifetime of y and so it can choose lifetimes that pass the borrow checker.


1: shared references are variant in the lifetime