Extending temporary's lifetimes

I can probably reasonably say that everyone has encountered the "this expression depends on a temporary that does not live long enough" error before. And the general solution is to extract out the intermediate expression to a new preceding let binding.

I, myself, personally don't recall a situation where that didn't work.

Is it just a implementation detail preventing such temporarys from having their lifetime extended or would it also break some existing programs?

Changing drop order for compiling programs is effectively a no-go at this point, so any additional behavior will have to be predicated on "this would not compile without hoisting the temporary."

The fact that this would complicate the already complex drop rules makes it scary. The current rule for temporaries is the consistent, if somewhat surprising in edge cases, rule that the scope of a temporarie is exactly as long as the scope of its immediately containing statement. (Consider the edge case of a trailing expression (not statement!) and be amazed by the inconsistency of consistency. The drop timing of a temporary in a tail expression return differs from that of the same expression as a return statement!)

So the temporary hoisting rule to make this work would have to be something along the lines of "if the scope of the containing statement is not enough to pass borrowck, extend the scope of the temporary to that of its containing scope. (I.e. as if it were a let binding beside it's containing statement)." (And oh boy! The behavior of this hoisting for tail expressions means that the temporary might live as long as the visually second containing scope! (I.e. changing expr to { expr } does not change how long temporaries last.)

Honestly, though this could be made to "just work :tm:," I think just supplying a copy-and-paste/machine-applicable fix hint is enough for this, because the drop timing rules to make this "just work :tm:" is more complicated than said drop timing rules are already (and hoisting scope leaves an annoying JavaScript-flavored aftertaste in my mouth that I don't particularly like).

TL;DR the current scoping rules for temporaries are embarrassingly subtle, and this would make it worse (if it avoids changing the behavior of correct-today code).

2 Likes

Thank you very much for the detailed response

RFC 66: Better Temporary Lifetimes was accepted in 2014, so supposedly we intend to fix this this someday.

However, RFC 66 is one of the oldest RFCs and was not really specified or discussed with the level of detail that we usually demand today. This has probably made the design and implementation work trickier. There’s some more recent discussion in the tracking issue.

2 Likes