Coming from C++, I'm rather surprised that this code is valid in Rust:
let x = &mut String::new();
x.push_str("Hello!");
In C++, you can't take the address of a temporary, and a temporary won't outlive the expression it appears in.
How long does the temporary live in Rust? And since x
is only a borrow, who is the owner of the string?
Rust's MIR provides some insight on the nature of temporaries; consider the following simplified case:
and the MIR it produces (standard comments replaced with mine):
You can see that an "invisible" owner receives a value before a reference is assigned to it and that the reference is dropped before the owner, as expected.
What I'm not sure about is why there is a seemingly useless
scope 2
and why the owner is not put inside any scope; I'm suspecting that MIR just isn't 100% ready yet.It's legal for the same reason it's illegal in C++ — because someone said that's how it should be.
The reference says:
Essentially, you can treat your code as:
See also:
From the Rust Reference:
This applies, because
String::new()
is a value expression and being just below&mut
it is in a place expression context. Now the reference operator only has to pass through this temporary memory location, so it becomes the value of the whole right side (including the&mut
).Since it is assigned to the variable it gets a lifetime until the end of the enclosing block.
This also answers this question about the difference between
and
In the second variant the temporary is passed into
as_str()
, so its lifetime ends at the end of the statement.