From 6e1eef6576dd3375a1f189d4cefd8da2cd0d1a27 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 27 Jan 2019 13:10:57 +0000 Subject: [PATCH 1/3] Clarify what access struct updates do --- src/expressions.md | 17 ++++++++++++----- src/expressions/struct-expr.md | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/expressions.md b/src/expressions.md index c098e6d96..36281e98d 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -98,11 +98,16 @@ expressions are value expressions. A *value expression* is an expression that represents an actual value. -The left operand of an [assignment][assign] or [compound assignment] expression -is a place expression context, as is the single operand of a unary [borrow], and -the operand of any [implicit borrow]. The discriminant or subject of a -[match expression][match] and right side of a [let statement] is also a place -expression context. All other expression contexts are value expression contexts. +The following contexts are *place expression* contexts: + +* The left operand of an [assignment][assign] or [compound assignment] expression. +* The operand of a unary [borrow] or [dereference] operator. +* The operand of a field expression. +* The indexed operand of an array indexing expression. +* The operand of any [implicit borrow]. +* The initializer of a [let statement]. +* The [scrutinee] of a [match expression][match]. +* The base of a [functional update] struct expression. > Note: Historically, place expressions were called *lvalues* and value > expressions were called *rvalues*. @@ -279,6 +284,7 @@ They are never allowed before: [closure expressions]: expressions/closure-expr.html [enum variant]: expressions/enum-variant-expr.html [field]: expressions/field-expr.html +[functional update]: expressions/struct-expr.html#functional-update-syntax [grouped]: expressions/grouped-expr.html [literals]: expressions/literal-expr.html [match]: expressions/match-expr.html @@ -316,6 +322,7 @@ They are never allowed before: [let statement]: statements.html#let-statements [Mutable `static` items]: items/static-items.html#mutable-statics [const contexts]: const_eval.html +[scrutinee]: glossary.html#scrutinee [slice]: types/slice.html [statement]: statements.html [static variables]: items/static-items.html diff --git a/src/expressions/struct-expr.md b/src/expressions/struct-expr.md index dc8c397c3..088b9c031 100644 --- a/src/expressions/struct-expr.md +++ b/src/expressions/struct-expr.md @@ -56,19 +56,23 @@ colon. A value of a [union] type can also be created using this syntax, except that it must specify exactly one field. +## Functional update syntax + A struct expression can terminate with the syntax `..` followed by an expression to denote a functional update. The expression following `..` (the -base) must have the same struct type as the new struct type being formed. The -entire expression denotes the result of constructing a new struct (with the -same type as the base expression) with the given values for the fields that -were explicitly specified and the values in the base expression for all other -fields. Just as with all struct expressions, all of the fields of the struct -must be [visible], even those not explicitly named. +base) must have the same struct type as the new struct type being formed. + +The entire expression uses the given values for the fields that were specified +and moves or copies the remaining fields from the base expression. Just as with +all struct expressions, all of the fields of the struct must be [visible], even +those not explicitly named. ```rust # struct Point3d { x: i32, y: i32, z: i32 } -let base = Point3d {x: 1, y: 2, z: 3}; -Point3d {y: 0, z: 10, .. base}; +let mut base = Point3d {x: 1, y: 2, z: 3}; +let y_ref = &mut base.y; +Point3d {y: 0, z: 10, .. base}; // OK, only base.x is accessed +drop(y_ref); ``` Struct expressions with curly braces can't be used directly in a [loop] or [if] From 37b648ac1a2771c07e28637ae8be3ded4c0ce643 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 27 Jan 2019 15:13:37 +0000 Subject: [PATCH 2/3] Address review comments --- src/expressions.md | 24 +++++++++++++----------- src/expressions/struct-expr.md | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/expressions.md b/src/expressions.md index 36281e98d..1e9676331 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -92,7 +92,7 @@ depends both on its own category and the context it occurs within. A *place expression* is an expression that represents a memory location. These expressions are [paths] which refer to local variables, [static variables], -[dereferences] (`*expr`), [array indexing] expressions (`expr[expr]`), +[dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`), [field] references (`expr.f`) and parenthesized place expressions. All other expressions are value expressions. @@ -100,13 +100,15 @@ A *value expression* is an expression that represents an actual value. The following contexts are *place expression* contexts: -* The left operand of an [assignment][assign] or [compound assignment] expression. -* The operand of a unary [borrow] or [dereference] operator. +* The left operand of an [assignment][assign] or [compound assignment] + expression. +* The operand of a unary [borrow] or [dereference][deref] operator. * The operand of a field expression. * The indexed operand of an array indexing expression. * The operand of any [implicit borrow]. * The initializer of a [let statement]. -* The [scrutinee] of a [match expression][match]. +* The [scrutinee] of a [`if let`], [`match`][match] or [`while let`] + expression. * The base of a [functional update] struct expression. > Note: Historically, place expressions were called *lvalues* and value @@ -124,8 +126,8 @@ move the value. Only the following place expressions may be moved out of: * [Temporary values](#temporary-lifetimes). * [Fields][field] of a place expression which can be moved out of and doesn't implement [`Drop`]. -* The result of [dereferencing] an expression with type [`Box`] and that can - also be moved out of. +* The result of [dereferencing][deref] an expression with type [`Box`] and + that can also be moved out of. Moving out of a place expression that evaluates to a local variable, the location is deinitialized and cannot be read from again until it is @@ -146,7 +148,7 @@ The following expressions can be mutable place expression contexts: * [Temporary values]. * [Fields][field], this evaluates the subexpression in a mutable place expression context. -* [Dereferences] of a `*mut T` pointer. +* [Dereferences][deref] of a `*mut T` pointer. * Dereference of a variable, or field of a variable, with type `&mut T`. Note: This is an exception to the requirement of the next rule. * Dereferences of a type that implements `DerefMut`, this then requires that @@ -244,7 +246,7 @@ Implicit borrows may be taken in the following expressions: * Left operand in [field] expressions. * Left operand in [call expressions]. * Left operand in [array indexing] expressions. -* Operand of the [dereference operator] \(`*`). +* Operand of the [dereference operator][deref] (`*`). * Operands of [comparison]. * Left operands of the [compound assignment]. @@ -286,6 +288,7 @@ They are never allowed before: [field]: expressions/field-expr.html [functional update]: expressions/struct-expr.html#functional-update-syntax [grouped]: expressions/grouped-expr.html +[`if let`]: expressions/if-expr.html#if-let-expressions [literals]: expressions/literal-expr.html [match]: expressions/match-expr.html [method-call]: expressions/method-call-expr.html @@ -293,6 +296,7 @@ They are never allowed before: [range expressions]: expressions/range-expr.html [struct]: expressions/struct-expr.html [tuple expressions]: expressions/tuple-expr.html +[`while let`]: expressions/loop-expr.html#predicate-pattern-loops [array expressions]: expressions/array-expr.html [array indexing]: expressions/array-expr.html#array-and-slice-indexing-expressions @@ -303,9 +307,7 @@ They are never allowed before: [cast]: expressions/operator-expr.html#type-cast-expressions [comparison]: expressions/operator-expr.html#comparison-operators [compound assignment]: expressions/operator-expr.html#compound-assignment-expressions -[dereferences]: expressions/operator-expr.html#the-dereference-operator -[dereferencing]: expressions/operator-expr.html#the-dereference-operator -[dereference operator]: expressions/operator-expr.html#the-dereference-operator +[deref]: expressions/operator-expr.html#the-dereference-operator [lazy boolean]: expressions/operator-expr.html#lazy-boolean-operators [negation]: expressions/operator-expr.html#negation-operators [overflow]: expressions/operator-expr.html#overflow diff --git a/src/expressions/struct-expr.md b/src/expressions/struct-expr.md index 088b9c031..ac278eb0b 100644 --- a/src/expressions/struct-expr.md +++ b/src/expressions/struct-expr.md @@ -63,8 +63,8 @@ expression to denote a functional update. The expression following `..` (the base) must have the same struct type as the new struct type being formed. The entire expression uses the given values for the fields that were specified -and moves or copies the remaining fields from the base expression. Just as with -all struct expressions, all of the fields of the struct must be [visible], even +and moves or copies the remaining fields from the base expression. As with all +struct expressions, all of the fields of the struct must be [visible], even those not explicitly named. ```rust From 3d8304d87b35c4c97588ed58378701ae3995edf2 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 27 Jan 2019 15:25:09 +0000 Subject: [PATCH 3/3] grammar fixes --- src/expressions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expressions.md b/src/expressions.md index 1e9676331..f30eb37c1 100644 --- a/src/expressions.md +++ b/src/expressions.md @@ -107,7 +107,7 @@ The following contexts are *place expression* contexts: * The indexed operand of an array indexing expression. * The operand of any [implicit borrow]. * The initializer of a [let statement]. -* The [scrutinee] of a [`if let`], [`match`][match] or [`while let`] +* The [scrutinee] of an [`if let`], [`match`][match], or [`while let`] expression. * The base of a [functional update] struct expression.