Temporaries in operands

Reference says:

Temporaries are also created to hold the result of operands to an expression while the other operands are evaluated. The temporaries are associated to the scope of the expression with that operand. Since the temporaries are moved from once the expression is evaluated, dropping them has no effect unless one of the operands to an expression breaks out of the expression, returns, or panics.

As i understand, every value expression in a place expression context, will lead to a temporary variable.
But expressions with multiple operands need to hold the value of each operand until all operands are evaluated, EVEN if it's operand is a value expression context.

So this text says temporaries are created in two situations: value in place context, and value in value context in expressions which have multiple operands. Places in place context do not need temporaries at all, even if they are in expressions with multiple operands.

Sorry for bad english

Am i correct?

Yes, that’s basically correct. One thing to add is that the two cases are a bit different regarding when the temporary value is dropped. The section before the one you quoted, on “temporary scopes”, describing the drop scopes for temporary variables, only applies to temporaries for holding “the result of that expression when used in a place context”,[1] as indicated in the beginning of that section, whereas these “temporaries” for operands use the more narrow drop scopes that exist for every single expression (so destruction happens immediately once evaluation leaves the expression [from innermost to outermost][2]).

You can see the difference e.g. by adapting the

loop {
    // Tuple expression doesn't finish evaluating so operands drop in reverse order
    (
        PrintOnDrop("Outer tuple first"),
        PrintOnDrop("Outer tuple second"),
        (
            PrintOnDrop("Inner tuple first"),
            PrintOnDrop("Inner tuple second"),
            break,
        ),
        PrintOnDrop("Never created"),
    );
}

example by adding something creating place-expression contexts, e.g.

PrintOnDrop("Inner tuple second").0, // <- changed

which will make this "Inner tuple second" drop later (its drop scope would then be the loop body).

(playground)


  1. and even for these there are further exceptions in the form of the special cases of temporary lifetime extension, as well as constant static promotion ↩︎

  2. relevant reference sentence: “When multiple scopes are left at once, such as when returning from a function, variables are dropped from the inside outwards.” ↩︎

I don't understand, why PrintOnDrop("Inner tuple second").0 drops later?

As mentioned

which is, as mentioned determined by

which states

since of all these “The body of an […] loop expression.” is the smallest thing that applies.

On the other hand, as mentioned

so the other 3 temporaries, which as not “the result of that expression when used in a place context”, have drop scopes according to the very section that you quoted,

so their drop scopes are the inner and outer tuple construction expressions, respectively. These scopes are nested lexically (compare this section) and

means we start with the inner tuple (the PrintOnDrop("Inner tuple first") is still associated to this, as an operator-related temporary; the PrintOnDrop("Inner tuple second").0 is not); then the outer tuple (giving you PrintOnDrop("Outer tuple second") and PrintOnDrop("Outer tuple first")), and finally as the outer-most of the three, the entire loop body is exited, which has the drop scope of the PrintOnDrop("Inner tuple second").0 expression (more precisely of the PrintOnDrop("Inner tuple second") expression, being used in a place-expression context, by the field access).

(this page)

1 Like

Thank's. This was a really complicated research on the reference!! :joy: