Skip to content

Commit ec8bb56

Browse files
authored
Merge pull request #518 from matthewjasper/update-clarification
Clarify what access struct updates do
2 parents db4f1f2 + 3d8304d commit ec8bb56

File tree

2 files changed

+34
-21
lines changed

2 files changed

+34
-21
lines changed

src/expressions.md

+22-13
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,24 @@ depends both on its own category and the context it occurs within.
9292

9393
A *place expression* is an expression that represents a memory location. These
9494
expressions are [paths] which refer to local variables, [static variables],
95-
[dereferences] (`*expr`), [array indexing] expressions (`expr[expr]`),
95+
[dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`),
9696
[field] references (`expr.f`) and parenthesized place expressions. All other
9797
expressions are value expressions.
9898

9999
A *value expression* is an expression that represents an actual value.
100100

101-
The left operand of an [assignment][assign] or [compound assignment] expression
102-
is a place expression context, as is the single operand of a unary [borrow], and
103-
the operand of any [implicit borrow]. The discriminant or subject of a
104-
[match expression][match] and right side of a [let statement] is also a place
105-
expression context. All other expression contexts are value expression contexts.
101+
The following contexts are *place expression* contexts:
102+
103+
* The left operand of an [assignment][assign] or [compound assignment]
104+
expression.
105+
* The operand of a unary [borrow] or [dereference][deref] operator.
106+
* The operand of a field expression.
107+
* The indexed operand of an array indexing expression.
108+
* The operand of any [implicit borrow].
109+
* The initializer of a [let statement].
110+
* The [scrutinee] of an [`if let`], [`match`][match], or [`while let`]
111+
expression.
112+
* The base of a [functional update] struct expression.
106113

107114
> Note: Historically, place expressions were called *lvalues* and value
108115
> expressions were called *rvalues*.
@@ -119,8 +126,8 @@ move the value. Only the following place expressions may be moved out of:
119126
* [Temporary values](#temporary-lifetimes).
120127
* [Fields][field] of a place expression which can be moved out of and
121128
doesn't implement [`Drop`].
122-
* The result of [dereferencing] an expression with type [`Box<T>`] and that can
123-
also be moved out of.
129+
* The result of [dereferencing][deref] an expression with type [`Box<T>`] and
130+
that can also be moved out of.
124131

125132
Moving out of a place expression that evaluates to a local variable, the
126133
location is deinitialized and cannot be read from again until it is
@@ -141,7 +148,7 @@ The following expressions can be mutable place expression contexts:
141148
* [Temporary values].
142149
* [Fields][field], this evaluates the subexpression in a mutable place
143150
expression context.
144-
* [Dereferences] of a `*mut T` pointer.
151+
* [Dereferences][deref] of a `*mut T` pointer.
145152
* Dereference of a variable, or field of a variable, with type `&mut T`. Note:
146153
This is an exception to the requirement of the next rule.
147154
* Dereferences of a type that implements `DerefMut`, this then requires that
@@ -239,7 +246,7 @@ Implicit borrows may be taken in the following expressions:
239246
* Left operand in [field] expressions.
240247
* Left operand in [call expressions].
241248
* Left operand in [array indexing] expressions.
242-
* Operand of the [dereference operator] \(`*`).
249+
* Operand of the [dereference operator][deref] (`*`).
243250
* Operands of [comparison].
244251
* Left operands of the [compound assignment].
245252

@@ -279,14 +286,17 @@ They are never allowed before:
279286
[closure expressions]: expressions/closure-expr.html
280287
[enum variant]: expressions/enum-variant-expr.html
281288
[field]: expressions/field-expr.html
289+
[functional update]: expressions/struct-expr.html#functional-update-syntax
282290
[grouped]: expressions/grouped-expr.html
291+
[`if let`]: expressions/if-expr.html#if-let-expressions
283292
[literals]: expressions/literal-expr.html
284293
[match]: expressions/match-expr.html
285294
[method-call]: expressions/method-call-expr.html
286295
[paths]: expressions/path-expr.html
287296
[range expressions]: expressions/range-expr.html
288297
[struct]: expressions/struct-expr.html
289298
[tuple expressions]: expressions/tuple-expr.html
299+
[`while let`]: expressions/loop-expr.html#predicate-pattern-loops
290300

291301
[array expressions]: expressions/array-expr.html
292302
[array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions
@@ -297,9 +307,7 @@ They are never allowed before:
297307
[cast]: expressions/operator-expr.html#type-cast-expressions
298308
[comparison]: expressions/operator-expr.html#comparison-operators
299309
[compound assignment]: expressions/operator-expr.html#compound-assignment-expressions
300-
[dereferences]: expressions/operator-expr.html#the-dereference-operator
301-
[dereferencing]: expressions/operator-expr.html#the-dereference-operator
302-
[dereference operator]: expressions/operator-expr.html#the-dereference-operator
310+
[deref]: expressions/operator-expr.html#the-dereference-operator
303311
[lazy boolean]: expressions/operator-expr.html#lazy-boolean-operators
304312
[negation]: expressions/operator-expr.html#negation-operators
305313
[overflow]: expressions/operator-expr.html#overflow
@@ -316,6 +324,7 @@ They are never allowed before:
316324
[let statement]: statements.html#let-statements
317325
[Mutable `static` items]: items/static-items.html#mutable-statics
318326
[const contexts]: const_eval.html
327+
[scrutinee]: glossary.html#scrutinee
319328
[slice]: types/slice.html
320329
[statement]: statements.html
321330
[static variables]: items/static-items.html

src/expressions/struct-expr.md

+12-8
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,23 @@ colon.
5656
A value of a [union] type can also be created using this syntax, except that it must
5757
specify exactly one field.
5858

59+
## Functional update syntax
60+
5961
A struct expression can terminate with the syntax `..` followed by an
6062
expression to denote a functional update. The expression following `..` (the
61-
base) must have the same struct type as the new struct type being formed. The
62-
entire expression denotes the result of constructing a new struct (with the
63-
same type as the base expression) with the given values for the fields that
64-
were explicitly specified and the values in the base expression for all other
65-
fields. Just as with all struct expressions, all of the fields of the struct
66-
must be [visible], even those not explicitly named.
63+
base) must have the same struct type as the new struct type being formed.
64+
65+
The entire expression uses the given values for the fields that were specified
66+
and moves or copies the remaining fields from the base expression. As with all
67+
struct expressions, all of the fields of the struct must be [visible], even
68+
those not explicitly named.
6769

6870
```rust
6971
# struct Point3d { x: i32, y: i32, z: i32 }
70-
let base = Point3d {x: 1, y: 2, z: 3};
71-
Point3d {y: 0, z: 10, .. base};
72+
let mut base = Point3d {x: 1, y: 2, z: 3};
73+
let y_ref = &mut base.y;
74+
Point3d {y: 0, z: 10, .. base}; // OK, only base.x is accessed
75+
drop(y_ref);
7276
```
7377

7478
Struct expressions with curly braces can't be used directly in a [loop] or [if]

0 commit comments

Comments
 (0)