Who owns data only refered by variable, but not asigned to any variable

let x = String::from("111"); 
let y = &String::from("222");

As I understand x owns "111".
But what owns "222" ?

1 Like
let a = &<stuff>;

is short-hand for

let a_owner = <stuff>;
let a = &a_owner;

when <stuff> is a not a place expression

6 Likes

Note that what @alice is saying is a special convenience rule that only applies to a few kinds of things like code of the form let … = &…; and syntactically similar things, like e. g. the same with &mut, or the reference pattern appearing in simple tuple, struct, or enum constructors.

This feature is called “temporary lifetime extension” and documented here. Some people might not like this feature all that much, because it's kind of an artificial special-case feature, but it can occasionally be useful to write your code a bit more tersely, and if you don't want to use it, you can easily avoid it. It's deliberately designed in a way that it only affects the meaning of code that most likely would otherwise not have compiled anyways.[1]


For competeness note that actually some instances of let x = &…; do compile successfully not due to temporary lifetime extension, but because of a second convenience feature that Rust has, called “static promotion” or “constant promotion”. Which cases exactly constant promotion applies to is unfortunately a bit underdocumented as of this writing (outside of somewhat hard to understand explanations on GitHub) but the basic idea of what it does (in case it applies) is that something like

let x = &2;

would become “translated” into

static X: i32 = 2;
let x = &X;

which will have the effect that x will be allowed to be a &'static i32 reference and live longer even then the scope of x, unlike what would be the case with the “temporary lifetime extension” feature. Constant promotion is designed even more carefully not to affect the behavior [2] of any code that would also compile without it, but it allows more programs to compile successfully, so e. g. you could explicitly call out the 'static lifetime of the reference to see that it's actually working, i. e. this compiles fine:

let x: &'static u32 = &2;

  1. Typically, without this lifetime extension, the code would only compile if the variable was left completely unused, but in realistic code, you would always actually always want to use the variable, and if you did, then compilation would indeed fail without the lifetime extension, because the reference would be used after its target, a temporary variable, has been dropped. ↩︎

  2. “behavior” is ignoring concerns like making the code faster or more memory efficient at run time ↩︎

5 Likes

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.