Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify what access struct updates do #518

Merged
merged 3 commits into from
Jan 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 22 additions & 13 deletions src/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,24 @@ 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.

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][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 an [`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
> expressions were called *rvalues*.
Expand All @@ -119,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<T>`] and that can
also be moved out of.
* The result of [dereferencing][deref] an expression with type [`Box<T>`] 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
Expand All @@ -141,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
Expand Down Expand Up @@ -239,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].

Expand Down Expand Up @@ -279,14 +286,17 @@ 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
[`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
[paths]: expressions/path-expr.html
[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
Expand All @@ -297,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
Expand All @@ -316,6 +324,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
Expand Down
20 changes: 12 additions & 8 deletions src/expressions/struct-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. 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]
Expand Down