Skip to content

Explicitly describe temporary drop order difference between return expr; and final block expression #452

Closed
@Havvy

Description

@Havvy
Contributor

Due to temporaries in the final expression of a block living longer than the block expression itself, there's actually a difference between a return expression and the final expression in a block. This should be explicitly documented so that we can link to people about it.

Associated Rust issue: rust-lang/rust#21114

Activity

pnkfelix

pnkfelix commented on Oct 30, 2018

@pnkfelix
Member

Its probably worth expanding this issue to also cover the difference between { ...; EXPR } and { ...; let x = EXPR; x }.

(To which many might say "... there's a difference between those two?" Yes, and its similar to the difference cited in this issues title.)

For the start of a neat test for illustrating this, you might look at the tests I added related to rust-lang/rust#54556, such as https://github.com/rust-lang/rust/blob/master/src/test/ui/nll/issue-54556-stephaneyfx.rs. Its diagnostic output under NLL tries hard to explain what the issue is:

link:

error[E0597]: `stmt` does not live long enough
  --> $DIR/issue-54556-stephaneyfx.rs:27:21
   |
LL |     let rows = Rows(&stmt);
   |                     ^^^^^ borrowed value does not live long enough
LL |     rows.map(|row| row).next()
   |     ------------------- a temporary with access to the borrow is created here ...
...
LL | }
   | -
   | |
   | `stmt` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `std::iter::Map<Rows<'_>, [closure@$DIR/issue-54556-stephaneyfx.rs:28:14: 28:23]>`
   |
   = note: The temporary is part of an expression at the end of a block. Consider forcing this temporary to be dropped sooner, before the block's local variables are dropped. For example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block.
pnkfelix

pnkfelix commented on Nov 9, 2018

@pnkfelix
Member

See also discussion here: rust-lang/rust#37612 which has examples where you get a deadlock because a temporary is surviving longer than the programmer expected, due to the these rules regarding the dynamic extent of temporaries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @pnkfelix@Havvy@matthewjasper

    Issue actions

      Explicitly describe temporary drop order difference between `return expr;` and final block expression · Issue #452 · rust-lang/reference