For a struct defined to contain a borrowed reference, does declaring an instance of it as mutable mean that the lifetime of the struct instance can change?
I read in an answer on Stackoverflow that lifetimes are burned into a variable once it is initialized and that lifetime can't change even if the variable is mutable. For example:
#[derive(Debug)]
struct Person<'a> {
email: &'a String,
}
fn main() {
let email_1 = "first_email@email.com".to_string();
let mut person;
{
let email_2 = "second_email@email.com".to_string();
person = Person {
email: &email_2,
};
println!("{:?}", person);
person.email = &email_1;
}
println!("{:?}", person);
}
And, as expected:
error[E0597]: `email_2` does not live long enough
--> src\main.rs:33:20
|
33 | email: &email_2,
| ^^^^^^^^ borrowed value does not live long enough
...
37 | }
| - `email_2` dropped here while still borrowed
38 | println!("{:?}", person);
| ------ borrow later used here
So, it seems like the lifetime information does get burned into the variable holding the struct instance. Although we assigned a different, longer-living reference to the Person instance's field, its lifetime was still inferred from and tied to the value that was initially assigned to it. Fair enough.
But wouldn't the following code then lead to a dangling reference in the Person instance's field?
#[derive(Debug)]
struct Person<'a> {
email: &'a String,
}
fn main() {
let email_1 = "first_email@email.com".to_string();
let mut person = Person {
email: &email_1,
};
{
let email_2 = "second_email@email.com".to_string();
person.email = &email_2;
}
println!("{:?}", person);
}
The lifetime of the Person instance should now be tied to the scope of email_1 and consequently it should be available for use in the last line, leading to the creation of a dangling reference in its field. Of course the borrow checker doesn't let this happen and raises this error:
error[E0597]: `email_2` does not live long enough
--> src\main.rs:34:24
|
34 | person.email = &email_2;
| ^^^^^^^^ borrowed value does not live long enough
35 | }
| - `email_2` dropped here while still borrowed
36 | println!("{:?}", person);
| ------ borrow later used here
But what principle is at play here?
Can the lifetime of a mutable struct instance change according to what reference is assigned to it? If so, why does the first piece of code fail?