Skip to content

Commit 32fc52b

Browse files
authored
Merge pull request #167 from Havvy/xvalue
Rename lvalue and rvalue to place and value expressions
2 parents 13f02d1 + bfc6eec commit 32fc52b

10 files changed

+190
-146
lines changed

src/expressions.md

+81-63
Original file line numberDiff line numberDiff line change
@@ -44,117 +44,125 @@ evaluated in the order given by their associativity.
4444
| `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
4545
| `return` `break` closures | |
4646

47-
## Lvalues and rvalues
47+
## Place Expressions and Value Expressions
4848

49-
Expressions are divided into two main categories: _lvalues_ and _rvalues_.
50-
Likewise within each expression, sub-expressions may occur in _lvalue context_
51-
or _rvalue context_. The evaluation of an expression depends both on its own
52-
category and the context it occurs within.
49+
Expressions are divided into two main categories: place expressions and
50+
value expressions. Likewise within each expression, sub-expressions may occur
51+
in either place context or value context. The evaluation of an expression
52+
depends both on its own category and the context it occurs within.
5353

54-
An lvalue is an expression that represents a memory location. These expressions
55-
are [paths](expressions/path-expr.html) which refer to local variables, static
56-
variables, function parameters, [dereferences]&nbsp;(`*expr`), [array indexing]
57-
expressions (`expr[expr]`), [field] references (`expr.f`) and parenthesized
58-
lvalue expressions. All other expressions are rvalues.
54+
A *place expression* is an expression that represents a memory location. These
55+
expressions are [paths] which refer to local variables, [static variables],
56+
[dereferences]&nbsp;(`*expr`), [array indexing] expressions (`expr[expr]`),
57+
[field] references (`expr.f`) and parenthesized place expressions. All other
58+
expressions are value expressions.
5959

60-
The left operand of an [assign]ment or [compound assignment] expression is an
61-
lvalue context, as is the single operand of a unary [borrow], and the operand
62-
of any [implicit borrow](#implicit-borrows). The discriminant or subject of a
63-
[match] expression and right side of a `let` is also an lvalue context. All
64-
other expression contexts are rvalue contexts.
60+
A *value expression* is an expression that represents an actual value.
61+
62+
The left operand of an [assignment][assign] or [compound assignment] expression
63+
is a place expression context, as is the single operand of a unary [borrow], and
64+
the operand of any [implicit borrow]. The discriminant or subject of a
65+
[match expression][match] and right side of a [let statement] is also a place
66+
expression context. All other expression contexts are value expression contexts.
67+
68+
> Note: Historically, place expressions were called *lvalues* and value
69+
> expressions were called *rvalues*.
6570
6671
### Moved and copied types
6772

68-
When an lvalue is evaluated in an _rvalue context_ or is bound by value in a
69-
pattern, it denotes the value held _in_ that memory location. If value is of a
70-
type that implements `Copy`, then the value will be copied. In the remaining
71-
situations if the type of the value is [`Sized`](the-sized-trait.html) it may
72-
be possible to move the value. Only the following lvalues may be moved out of:
73+
When a place expression is evaluated in a value expression context, or is bound
74+
by value in a pattern, it denotes the value held _in_ that memory location. If
75+
the type of that value implements `Copy`, then the value will be copied. In the
76+
remaining situations if that type is [`Sized`](the-sized-trait.html), then it
77+
may be possible to move the value. Only the following place expressions may be
78+
moved out of:
7379

74-
* [Variables](variables.html) which are not currently borrowed.
80+
* [Variables] which are not currently borrowed.
7581
* [Temporary values](#temporary-lifetimes).
76-
* [Field]s of an lvalue which can be moved out of and
82+
* [Fields][field] of a place expression which can be moved out of and
7783
doesn't implement [`Drop`](the-drop-trait.html).
78-
* The result of [dereferencing] an expression with type `Box<T>` and that can
84+
* The result of [dereferencing] an expression with type [`Box<T>`] and that can
7985
also be moved out of.
8086

81-
Moving out of an lvalue deinitializes that location (if it comes from a local
82-
variable), so that it can't be read from again. In all other cases, trying to
83-
use an lvalue in an rvalue context is an error.
87+
Moving out of a place expression that evaluates to a local variable, the
88+
location is deinitialized and cannot be read from again until it is
89+
reinitialized. In all other cases, trying to use a place expression in a value
90+
expression context is an error.
8491

8592
### Mutability
8693

87-
For an lvalue to be [assign]ed to, mutably [borrow]ed,
88-
[implicitly mutably borrowed](#implicit-borrows)
89-
or bound to a pattern containing `ref mut` it must be _mutable_, we call these
90-
contexts _mutable_ lvalue contexts, other lvalue contexts are called
91-
_immutable_.
94+
For a place expression to be [assigned][assign] to, mutably [borrowed][borrow],
95+
[implicitly mutably borrowed], or bound to a pattern containing `ref mut` it
96+
must be _mutable_. We call these *mutable place expressions*. In contrast,
97+
other place expressions are called *immutable place expressions*.
9298

93-
The following expressions can create mutable lvalues:
99+
The following expressions can be mutable place expression contexts:
94100

95-
* Mutable [variables](variables.html), which are not currently borrowed.
96-
* [Mutable `static` items](items/static-items.html#mutable-statics).
97-
* [Temporary values](#temporary-lifetimes).
98-
* [Field]s, this evaluates the subexpression in a mutable lvalue context.
101+
* Mutable [variables], which are not currently borrowed.
102+
* [Mutable `static` items].
103+
* [Temporary values].
104+
* [Fields][field], this evaluates the subexpression in a mutable place
105+
expression context.
99106
* [Dereferences] of a `*mut T` pointer.
100107
* Dereference of a variable, or field of a variable, with type `&mut T`. Note:
101-
this is an exception to the requirement for the next rule.
108+
This is an exception to the requirement of the next rule.
102109
* Dereferences of a type that implements `DerefMut`, this then requires that
103-
the value being dereferenced is evaluated is a mutable lvalue context.
110+
the value being dereferenced is evaluated is a mutable place expression context.
104111
* [Array indexing] of a type that implements `DerefMut`, this
105-
then evaluates the value being indexed (but not the index) in mutable lvalue
106-
context.
112+
then evaluates the value being indexed, but not the index, in mutable place
113+
expression context.
107114

108115
### Temporary lifetimes
109116

110-
When using an rvalue in most lvalue contexts, a temporary unnamed lvalue is
111-
created and used instead, if not promoted to `'static`. Promotion of an
112-
rvalue expression to a `'static` slot occurs when the expression could be
117+
When using a value expression in most place expression contexts, a temporary
118+
unnamed memory location is created initialized to that value and the expression
119+
evaluates to that location instead, except if promoted to `'static`. Promotion
120+
of a value expression to a `'static` slot occurs when the expression could be
113121
written in a constant, borrowed, and dereferencing that borrow where the
114122
expression was the originally written, without changing the runtime behavior.
115123
That is, the promoted expression can be evaluated at compile-time and the
116-
resulting value does not contain interior mutability or destructors (these
124+
resulting value does not contain [interior mutability] or [destructors] (these
117125
properties are determined based on the value where possible, e.g. `&None`
118126
always has the type `&'static Option<_>`, as it contains nothing disallowed).
119127
Otherwise, the lifetime of temporary values is typically
120128

121129
- the innermost enclosing statement; the tail expression of a block is
122130
considered part of the statement that encloses the block, or
123131
- the condition expression or the loop conditional expression if the
124-
temporary is created in the condition expression of an `if` or an `if`/`else`
125-
or in the loop conditional expression of a `while` expression.
132+
temporary is created in the condition expression of an `if` or in the loop
133+
conditional expression of a `while` expression.
126134

127-
When a temporary rvalue is being created that is assigned into a `let`
128-
declaration, however, the temporary is created with the lifetime of the
129-
enclosing block instead, as using the enclosing statement (the `let`
130-
declaration) would be a guaranteed error (since a pointer to the temporary
135+
When a temporary value expression is being created that is assigned into a
136+
[`let` declaration][let], however, the temporary is created with the lifetime of
137+
the enclosing block instead, as using the enclosing [`let` declaration][let]
138+
would be a guaranteed error (since a pointer to the temporary
131139
would be stored into a variable, but the temporary would be freed before the
132140
variable could be used). The compiler uses simple syntactic rules to decide
133141
which values are being assigned into a `let` binding, and therefore deserve a
134142
longer temporary lifetime.
135143

136144
Here are some examples:
137145

138-
- `let x = foo(&temp())`. The expression `temp()` is an rvalue. As it
146+
- `let x = foo(&temp())`. The expression `temp()` is a value expression. As it
139147
is being borrowed, a temporary is created which will be freed after
140-
the innermost enclosing statement (the `let` declaration, in this case).
148+
the innermost enclosing statement; in this case, the `let` declaration.
141149
- `let x = temp().foo()`. This is the same as the previous example,
142150
except that the value of `temp()` is being borrowed via autoref on a
143151
method-call. Here we are assuming that `foo()` is an `&self` method
144152
defined in some trait, say `Foo`. In other words, the expression
145153
`temp().foo()` is equivalent to `Foo::foo(&temp())`.
146154
- `let x = if foo(&temp()) {bar()} else {baz()};`. The expression `temp()` is
147-
an rvalue. As the temporary is created in the condition expression
148-
of an `if`/`else`, it will be freed at the end of the condition expression
149-
(in this example before the call to `bar` or `baz` is made).
155+
a value expression. As the temporary is created in the condition expression
156+
of an `if`, it will be freed at the end of the condition expression;
157+
in this example before the call to `bar` or `baz` is made.
150158
- `let x = if temp().must_run_bar {bar()} else {baz()};`.
151159
Here we assume the type of `temp()` is a struct with a boolean field
152160
`must_run_bar`. As the previous example, the temporary corresponding to
153161
`temp()` will be freed at the end of the condition expression.
154162
- `while foo(&temp()) {bar();}`. The temporary containing the return value from
155163
the call to `temp()` is created in the loop conditional expression. Hence it
156-
will be freed at the end of the loop conditional expression (in this example
157-
before the call to `bar` if the loop body is executed).
164+
will be freed at the end of the loop conditional expression; in this example
165+
before the call to `bar` if the loop body is executed.
158166
- `let x = &temp()`. Here, the same temporary is being assigned into
159167
`x`, rather than being passed as a parameter, and hence the
160168
temporary's lifetime is considered to be the enclosing block.
@@ -164,12 +172,13 @@ Here are some examples:
164172
- `let x = [ &temp() ]`. As in the previous case, the
165173
temporary is assigned into an array which is then assigned into a
166174
binding, and hence it is given the lifetime of the enclosing block.
167-
- `let ref x = temp()`. In this case, the temporary is created using a ref binding,
168-
but the result is the same: the lifetime is extended to the enclosing block.
175+
- `let ref x = temp()`. In this case, the temporary is created using a ref
176+
binding, but the result is the same: the lifetime is extended to the enclosing
177+
block.
169178

170179
### Implicit Borrows
171180

172-
Certain expressions will treat an expression as an lvalue by implicitly
181+
Certain expressions will treat an expression as a place expression by implicitly
173182
borrowing it. For example, it is possible to compare two unsized [slices] for
174183
equality directly, because the `==` operator implicitly borrows it's operands:
175184

@@ -192,7 +201,7 @@ Implicit borrows may be taken in the following expressions:
192201
* Left operand in [field] expressions.
193202
* Left operand in [call expressions].
194203
* Left operand in [array indexing] expressions.
195-
* Operand of the [dereference] operator (`*`).
204+
* Operand of the [dereference operator] \(`*`).
196205
* Operands of [comparison].
197206
* Left operands of the [compound assignment].
198207

@@ -236,7 +245,7 @@ to be ran.
236245
## Overloading Traits
237246

238247
Many of the following operators and expressions can also be overloaded for
239-
other types using traits in `std::ops` or `std::cmp`, these traits here also
248+
other types using traits in `std::ops` or `std::cmp`. These traits also
240249
exist in `core::ops` and `core::cmp` with the same names.
241250

242251
[block expressions]: expressions/block-expr.html
@@ -270,5 +279,14 @@ exist in `core::ops` and `core::cmp` with the same names.
270279
[overflow]: expressions/operator-expr.html#overflow
271280

272281
[destructors]: destructors.html
273-
[interior-mutability]: interior-mutability.html
282+
[interior mutability]: interior-mutability.html
283+
[`Box<T>`]: ../std/boxed/struct.Box.html
284+
[implicit borrow]: #implicit-borrows
285+
[implicitly mutably borrowed]: #implicit-borrows
286+
[let]: statements.html#let-statements
287+
[let statement]: statements.html#let-statements
288+
[Mutable `static` items]: items/static-items.html#mutable-statics
274289
[slice]: types.html#array-and-slice-types
290+
[static variables]: items/static-items.html
291+
[Temporary values]: #temporary-lifetimes
292+
[Variables]: variables.html

src/expressions/array-expr.md

+11-10
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,17 @@ greater than 1 then this requires that the type of `a` is
3838
3939
[Array and slice](types.html#array-and-slice-types)-typed expressions can be
4040
indexed by writing a square-bracket-enclosed expression (the index) after them.
41-
When the array is mutable, the resulting
42-
[lvalue](expressions.html#lvalues-and-rvalues) can be assigned to.
41+
When the array is mutable, the resulting [memory location] can be assigned to.
4342
For other types an index expression `a[b]` is equivalent to
4443
`*std::ops::Index::index(&a, b)`, or `*std::opsIndexMut::index_mut(&mut a, b)`
45-
in a mutable lvalue context. Just as with methods, Rust will also insert
46-
dereference operations on `a` repeatedly to find an implementation.
44+
in a mutable place expression context. Just as with methods, Rust will also
45+
insert dereference operations on `a` repeatedly to find an implementation.
4746

4847
Indices are zero-based, and are of type `usize` for arrays and slices. Array
49-
access is a [constant expression](expressions.html#constant-expressions), so bounds can be
50-
checked at compile-time for constant arrays with a constant index value.
51-
Otherwise a check will be performed at run-time that will put the thread in a
52-
_panicked state_ if it fails.
48+
access is a [constant expression], so
49+
bounds can be checked at compile-time for constant arrays with a constant index
50+
value. Otherwise a check will be performed at run-time that will put the thread
51+
in a _panicked state_ if it fails.
5352

5453
```rust,should_panic
5554
([1, 2, 3, 4])[2]; // Evaluates to 3
@@ -69,6 +68,8 @@ arr[10]; // panics
6968
The array index expression can be implemented for types other than arrays and slices
7069
by implementing the [Index] and [IndexMut] traits.
7170

72-
[Index]: https://doc.rust-lang.org/std/ops/trait.Index.html
73-
[IndexMut]: https://doc.rust-lang.org/std/ops/trait.IndexMut.html
7471
[_Expression_]: expressions.html
72+
[memory location]: expressions.html#place-expressions-and-value-expressions
73+
[Index]: ../std/ops/trait.Index.html
74+
[IndexMut]: ../std/ops/trait.IndexMut.html
75+
[constant expression]: expressions.html#constant-expressions

src/expressions/block-expr.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
> &nbsp;&nbsp; `}`
1010
1111
A _block expression_ is similar to a module in terms of the declarations that
12-
are possible, but can also contain [statements](statements.html) and end with
13-
an expression. Each block conceptually introduces a new namespace scope. Use
12+
are possible, but can also contain [statements] and end with
13+
an [expression]. Each block conceptually introduces a new namespace scope. Use
1414
items can bring new names into scopes and declared items are in scope for only
1515
the block itself.
1616

1717
A block will execute each statement sequentially, and then execute the
18-
expression (if given). If the block doesn't end in an expression, its value is
18+
expression, if given. If the block doesn't end in an expression, its value is
1919
`()`:
2020

2121
```rust
@@ -30,9 +30,9 @@ let x: i32 = { println!("Hello."); 5 };
3030
assert_eq!(5, x);
3131
```
3232

33-
Blocks are always [rvalues](expressions.html#lvalues-and-rvalues) and evaluate the last
34-
expression in rvalue context. This can be used to force moving a value
35-
if really needed.
33+
Blocks are always [value expressions] and evaluate the last expression in
34+
value expression context. This can be used to force moving a value if really
35+
needed.
3636

3737
## `unsafe` blocks
3838

@@ -60,3 +60,6 @@ let a = unsafe { f() };
6060
[_InnerAttribute_]: attributes.html
6161
[_Statement_]: statements.html
6262
[_Expression_]: expressions.html
63+
[expression]: expressions.html
64+
[statements]: statements.html
65+
[value expressions]: expressions.html#place-expressions-and-value-expressions

src/expressions/field-expr.md

+11-8
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
> &nbsp;&nbsp; [_Expression_] `.` [IDENTIFIER]
66
77
A _field expression_ consists of an expression followed by a single dot and an
8-
[identifier](identifiers.html), when not immediately followed by a
9-
parenthesized expression-list (the latter is always a [method call
10-
expression](expressions/method-call-expr.html)). A field expression denotes a field of a
11-
[struct](types.html#struct-types) or [union](items/unions.html). To call a
12-
function stored in a struct parentheses are needed around the field expression
8+
[identifier], when not immediately followed by a parenthesized expression-list
9+
(the latter is always a [method call expression]). A field expression denotes a
10+
field of a [struct] or [union]. To call a function stored in a struct,
11+
parentheses are needed around the field expression.
1312

1413
```rust,ignore
1514
mystruct.myfield;
@@ -19,9 +18,8 @@ mystruct.method(); // Method expression
1918
(mystruct.function_field)() // Call expression containing a field expression
2019
```
2120

22-
A field access is an [lvalue](expressions.html#lvalues-and-rvalues) referring
23-
to the location of that field. When the subexpression is
24-
[mutable](expressions.html#mutability), the field expression is also mutable.
21+
A field access is a [place expression] referring to the location of that field.
22+
When the subexpression is [mutable], the field expression is also mutable.
2523

2624
Also, if the type of the expression to the left of the dot is a pointer, it is
2725
automatically dereferenced as many times as necessary to make the field access
@@ -49,3 +47,8 @@ let d: String = x.f3; // Move out of x.f3
4947

5048
[_Expression_]: expressions.html
5149
[IDENTIFIER]: identifiers.html
50+
[method call expression]: expressions/method-call-expr.html
51+
[struct]: items/structs.html
52+
[union]: items/unions.html
53+
[place expression]: expressions.html#place-expressions-and-value-expressions
54+
[mutable]: expressions.html#mutability

0 commit comments

Comments
 (0)