Skip to content

Commit c9ee32d

Browse files
committed
Document temporary lifetime rules in the reference
Fixes rust-lang#12032
1 parent 7b78538 commit c9ee32d

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/doc/reference.md

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2486,9 +2486,35 @@ declaration, however, the temporary is created with the lifetime of
24862486
the enclosing block instead, as using the enclosing statement (the
24872487
`let` declaration) would be a guaranteed error (since a pointer to the
24882488
temporary would be stored into a variable, but the temporary would be
2489-
freed before the variable could be used). The compiler uses simple
2490-
syntactic rules to decide which values are being assigned into a `let`
2491-
binding, and therefore deserve a longer temporary lifetime.
2489+
freed before the variable could be used).
2490+
2491+
The compiler uses simple syntactic rules to decide which values are being
2492+
assigned into a `let` binding, and therefore deserve a longer temporary
2493+
lifetime. We express them more formally based on three grammars:
2494+
2495+
1. `E&`, which matches expressions like `&<rvalue>` that
2496+
own a pointer into the stack.
2497+
2498+
2. `P&`, which matches patterns like `ref x` or `(ref x, ref
2499+
y)` that produce ref bindings into the value they are
2500+
matched against or something (at least partially) owned by
2501+
the value they are matched against. (By partially owned,
2502+
I mean that creating a binding into a ref-counted or managed value
2503+
would still count.)
2504+
2505+
3. `ET`, which matches both rvalues like `foo()` as well as lvalues
2506+
based on rvalues like `foo().x[2].y`.
2507+
2508+
With these grammers, a subexpression `<rvalue>` that appears in a let
2509+
initializer `let pat [: ty] = expr` has an extended temporary lifetime if any
2510+
of the following conditions are met:
2511+
2512+
1. `pat` matches `P&` and `expr` matches `ET` (covers cases where `pat` creates
2513+
ref bindings into an rvalue produced by `expr`)
2514+
2. `ty` is a borrowed pointer and `expr` matches `ET` (covers cases where
2515+
coercion creates a borrow)
2516+
3. `expr` matches `E&` (covers cases `expr` borrows an rvalue that is then
2517+
assigned to memory (at least partially) owned by the binding)
24922518

24932519
Here are some examples:
24942520

0 commit comments

Comments
 (0)