@@ -2486,9 +2486,35 @@ declaration, however, the temporary is created with the lifetime of
2486
2486
the enclosing block instead, as using the enclosing statement (the
2487
2487
` let ` declaration) would be a guaranteed error (since a pointer to the
2488
2488
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)
2492
2518
2493
2519
Here are some examples:
2494
2520
0 commit comments