Skip to content

Commit 4249fb4

Browse files
authored
Merge pull request #1591 from chorman0773/spec-add-identifiers-exprs
Add Spec Identifier Syntax to expressions.md and subchapters
2 parents 75df12e + 3e57a06 commit 4249fb4

20 files changed

+623
-7
lines changed

src/expressions.md

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
r[expr]
12
# Expressions
23

4+
r[expr.syntax]
35
> **<sup>Syntax</sup>**\
46
> _Expression_ :\
57
> &nbsp;&nbsp; &nbsp;&nbsp; _ExpressionWithoutBlock_\
@@ -43,20 +45,29 @@
4345
> &nbsp;&nbsp; &nbsp;&nbsp; | [_MatchExpression_]\
4446
> &nbsp;&nbsp; )
4547
48+
r[expr.intro]
4649
An expression may have two roles: it always produces a *value*, and it may have *effects* (otherwise known as "side effects").
50+
51+
r[expr.evaluation]
4752
An expression *evaluates to* a value, and has effects during *evaluation*.
53+
54+
r[expr.operands]
4855
Many expressions contain sub-expressions, called the *operands* of the expression.
56+
57+
r[expr.behavior]
4958
The meaning of each kind of expression dictates several things:
5059

5160
* Whether or not to evaluate the operands when evaluating the expression
5261
* The order in which to evaluate the operands
5362
* How to combine the operands' values to obtain the value of the expression
5463

64+
r[expr.structure]
5565
In this way, the structure of expressions dictates the structure of execution.
5666
Blocks are just another kind of expression, so blocks, statements, expressions, and blocks again can recursively nest inside each other to an arbitrary depth.
5767

5868
> **Note**: We give names to the operands of expressions so that we may discuss them, but these names are not stable and may be changed.
5969
70+
r[expr.precedence]
6071
## Expression precedence
6172

6273
The precedence of Rust operators and expressions is ordered as follows, going from strong to weak.
@@ -84,8 +95,10 @@ Binary Operators at the same precedence level are grouped in the order given by
8495
| `=` `+=` `-=` `*=` `/=` `%=` <br> `&=` <code>&#124;=</code> `^=` `<<=` `>>=` | right to left |
8596
| `return` `break` closures | |
8697

98+
r[expr.operand-order]
8799
## Evaluation order of operands
88100

101+
r[expr.operand-order.default]
89102
The following list of expressions all evaluate their operands the same way, as described after the list.
90103
Other expressions either don't take operands or evaluate them conditionally as described on their respective pages.
91104

@@ -109,6 +122,7 @@ Other expressions either don't take operands or evaluate them conditionally as d
109122
* Range expression
110123
* Return expression
111124

125+
r[expr.operand-order.operands-before-primary]
112126
The operands of these expressions are evaluated prior to applying the effects of the expression.
113127
Expressions taking multiple operands are evaluated left to right as written in the source code.
114128

@@ -130,19 +144,28 @@ assert_eq!(
130144

131145
> **Note**: Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions.
132146
147+
r[expr.place-value]
133148
## Place Expressions and Value Expressions
134149

150+
r[expr.place-value.intro]
135151
Expressions are divided into two main categories: place expressions and value expressions;
136152
there is also a third, minor category of expressions called assignee expressions.
137153
Within each expression, operands may likewise occur in either place context or value context.
138154
The evaluation of an expression depends both on its own category and the context it occurs within.
139155

156+
r[expr.place-value.place-memory-location]
140157
A *place expression* is an expression that represents a memory location.
158+
159+
r[expr.place-value.place-expr-kinds]
141160
These expressions are [paths] which refer to local variables, [static variables], [dereferences][deref] (`*expr`), [array indexing] expressions (`expr[expr]`), [field] references (`expr.f`) and parenthesized place expressions.
161+
162+
r[expr.place-value.value-expr-kinds]
142163
All other expressions are value expressions.
143164

165+
r[expr.place-value.value-result]
144166
A *value expression* is an expression that represents an actual value.
145167

168+
r[expr.place-value.place-context]
146169
The following contexts are *place expression* contexts:
147170

148171
* The left operand of a [compound assignment] expression.
@@ -157,6 +180,7 @@ The following contexts are *place expression* contexts:
157180

158181
> Note: Historically, place expressions were called *lvalues* and value expressions were called *rvalues*.
159182
183+
r[expr.place-value.assignee]
160184
An *assignee expression* is an expression that appears in the left operand of an [assignment][assign] expression.
161185
Explicitly, the assignee expressions are:
162186

@@ -169,29 +193,44 @@ Explicitly, the assignee expressions are:
169193
fields).
170194
- [Unit structs][_StructExpression_].
171195

196+
r[expr.place-value.parenthesis]
172197
Arbitrary parenthesisation is permitted inside assignee expressions.
173198

199+
r[expr.move]
174200
### Moved and copied types
175201

202+
r[expr.move.intro]
176203
When a place expression is evaluated in a value expression context, or is bound by value in a pattern, it denotes the value held _in_ that memory location.
204+
205+
r[expr.move.copy]
177206
If the type of that value implements [`Copy`], then the value will be copied.
207+
208+
r[expr.move.requires-sized]
178209
In the remaining situations, if that type is [`Sized`], then it may be possible to move the value.
210+
211+
r[expr.move.movable-place]
179212
Only the following place expressions may be moved out of:
180213

181214
* [Variables] which are not currently borrowed.
182215
* [Temporary values](#temporaries).
183216
* [Fields][field] of a place expression which can be moved out of and don't implement [`Drop`].
184217
* The result of [dereferencing][deref] an expression with type [`Box<T>`] and that can also be moved out of.
185218

219+
r[expr.move.deinitialization]
186220
After 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 reinitialized.
221+
222+
r[expr.move.place-invalid]
187223
In all other cases, trying to use a place expression in a value expression context is an error.
188224

225+
r[expr.mut]
189226
### Mutability
190227

228+
r[expr.mut.intro]
191229
For a place expression to be [assigned][assign] to, mutably [borrowed][borrow], [implicitly mutably borrowed], or bound to a pattern containing `ref mut`, it must be _mutable_.
192230
We call these *mutable place expressions*.
193231
In contrast, other place expressions are called *immutable place expressions*.
194232

233+
r[expr.mut.valid-places]
195234
The following expressions can be mutable place expression contexts:
196235

197236
* Mutable [variables] which are not currently borrowed.
@@ -206,14 +245,17 @@ The following expressions can be mutable place expression contexts:
206245
* [Array indexing] of a type that implements `IndexMut`:
207246
this then evaluates the value being indexed, but not the index, in mutable place expression context.
208247

248+
r[expr.temporary]
209249
### Temporaries
210250

211251
When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value.
212252
The expression evaluates to that location instead, except if [promoted] to a `static`.
213253
The [drop scope] of the temporary is usually the end of the enclosing statement.
214254

255+
r[expr.implicit-borrow]
215256
### Implicit Borrows
216257

258+
r[expr.implicit-borrow-intro]
217259
Certain expressions will treat an expression as a place expression by implicitly borrowing it.
218260
For example, it is possible to compare two unsized [slices][slice] for equality directly, because the `==` operator implicitly borrows its operands:
219261

@@ -230,6 +272,7 @@ let b: &[i32];
230272
::std::cmp::PartialEq::eq(&*a, &*b);
231273
```
232274

275+
r[expr.implicit-borrow.application]
233276
Implicit borrows may be taken in the following expressions:
234277

235278
* Left operand in [method-call] expressions.
@@ -240,25 +283,28 @@ Implicit borrows may be taken in the following expressions:
240283
* Operands of [comparison].
241284
* Left operands of the [compound assignment].
242285

286+
r[expr.overload]
243287
## Overloading Traits
244288

245289
Many of the following operators and expressions can also be overloaded for other types using traits in `std::ops` or `std::cmp`.
246290
These traits also exist in `core::ops` and `core::cmp` with the same names.
247291

292+
r[expr.attr]
248293
## Expression Attributes
249294

295+
r[expr.attr.restriction]
250296
[Outer attributes][_OuterAttribute_] before an expression are allowed only in a few specific cases:
251297

252298
* Before an expression used as a [statement].
253299
* Elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions.
254300
* The tail expression of [block expressions].
255301
<!-- Keep list in sync with block-expr.md -->
256302

303+
r[expr.attr.never-before]
257304
They are never allowed before:
258305
* [Range][_RangeExpression_] expressions.
259306
* Binary operator expressions ([_ArithmeticOrLogicalExpression_], [_ComparisonExpression_], [_LazyBooleanExpression_], [_TypeCastExpression_], [_AssignmentExpression_], [_CompoundAssignmentExpression_]).
260307

261-
262308
[block expressions]: expressions/block-expr.md
263309
[call expressions]: expressions/call-expr.md
264310
[field]: expressions/field-expr.md

src/expressions/array-expr.md

+31
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
r[expr.array]
12
# Array and array index expressions
23

34
## Array expressions
45

6+
r[expr.array.syntax]
57
> **<sup>Syntax</sup>**\
68
> _ArrayExpression_ :\
79
> &nbsp;&nbsp; `[` _ArrayElements_<sup>?</sup> `]`
@@ -10,23 +12,45 @@
1012
> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] ( `,` [_Expression_] )<sup>\*</sup> `,`<sup>?</sup>\
1113
> &nbsp;&nbsp; | [_Expression_] `;` [_Expression_]
1214
15+
r[expr.array.constructor]
1316
*Array expressions* construct [arrays][array].
1417
Array expressions come in two forms.
1518

19+
r[expr.array.array]
1620
The first form lists out every value in the array.
21+
22+
r[expr.array.array-syntax]
1723
The syntax for this form is a comma-separated list of expressions of uniform type enclosed in square brackets.
24+
25+
r[expr.array.array-behavior]
1826
This produces an array containing each of these values in the order they are written.
1927

28+
r[expr.array.repeat]
2029
The syntax for the second form is two expressions separated by a semicolon (`;`) enclosed in square brackets.
30+
31+
r[expr.array.repeat-operand]
2132
The expression before the `;` is called the *repeat operand*.
33+
34+
r[expr.array.length-operand]
2235
The expression after the `;` is called the *length operand*.
36+
37+
r[expr.array.length-restriction]
2338
It must have type `usize` and be a [constant expression], such as a [literal] or a [constant item].
39+
40+
r[expr.array.repeat-behavior]
2441
An array expression of this form creates an array with the length of the value of the length operand with each element being a copy of the repeat operand.
2542
That is, `[a; b]` creates an array containing `b` copies of the value of `a`.
43+
44+
r[expr.array.repeat-copy]
2645
If the length operand has a value greater than 1 then this requires that the type of the repeat operand is [`Copy`] or that it must be a [path] to a constant item.
2746

47+
r[expr.array.repeat-const-item]
2848
When the repeat operand is a constant item, it is evaluated the length operand's value times.
49+
50+
r[expr.array.repeat-evaluation-zero]
2951
If that value is `0`, then the constant item is not evaluated at all.
52+
53+
r[expr.array.repeat-non-const]
3054
For expressions that are not a constant item, it is evaluated exactly once, and then the result is copied the length operand's value times.
3155

3256
```rust
@@ -39,19 +63,25 @@ const EMPTY: Vec<i32> = Vec::new();
3963
[EMPTY; 2];
4064
```
4165

66+
r[expr.array.index]
4267
## Array and slice indexing expressions
4368

4469
> **<sup>Syntax</sup>**\
4570
> _IndexExpression_ :\
4671
> &nbsp;&nbsp; [_Expression_] `[` [_Expression_] `]`
4772
73+
r[expr.array.index.array]
4874
[Array] and [slice]-typed values can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them.
4975
When the array is mutable, the resulting [memory location] can be assigned to.
5076

77+
r[expr.array.index.trait]
5178
For other types an index expression `a[b]` is equivalent to `*std::ops::Index::index(&a, b)`, or `*std::ops::IndexMut::index_mut(&mut a, b)` in a mutable place expression context.
5279
Just as with methods, Rust will also insert dereference operations on `a` repeatedly to find an implementation.
5380

81+
r[expr.array.index.zero-index]
5482
Indices are zero-based for arrays and slices.
83+
84+
r[expr.array.index.const]
5585
Array access is a [constant expression], so bounds can be checked at compile-time with a constant index value.
5686
Otherwise a check will be performed at run-time that will put the thread in a _panicked state_ if it fails.
5787

@@ -73,6 +103,7 @@ let arr = ["a", "b"];
73103
arr[10]; // warning: index out of bounds
74104
```
75105

106+
r[expr.array.index.trait-impl]
76107
The array index expression can be implemented for types other than arrays and slices by implementing the [Index] and [IndexMut] traits.
77108

78109
[`Copy`]: ../special-types-and-traits.md#copy

src/expressions/await-expr.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1+
r[expr.await]
12
# Await expressions
23

4+
r[expr.await.syntax]
35
> **<sup>Syntax</sup>**\
46
> _AwaitExpression_ :\
57
> &nbsp;&nbsp; [_Expression_] `.` `await`
68
9+
r[expr.await.intro]
710
An `await` expression is a syntactic construct for suspending a computation
811
provided by an implementation of `std::future::IntoFuture` until the given
912
future is ready to produce a value.
13+
14+
r[expr.await.construct]
1015
The syntax for an await expression is an expression with a type that implements the [`IntoFuture`] trait, called the *future operand*, then the token `.`, and then the `await` keyword.
16+
17+
r[expr.await.allowed-positions]
1118
Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or [`async` block].
1219

20+
r[expr.await.effects]
1321
More specifically, an await expression has the following effect.
1422

1523
1. Create a future by calling [`IntoFuture::into_future`] on the future operand.
@@ -21,11 +29,13 @@ More specifically, an await expression has the following effect.
2129

2230
> **Edition differences**: Await expressions are only available beginning with Rust 2018.
2331
32+
r[expr.await.task]
2433
## Task context
2534

2635
The task context refers to the [`Context`] which was supplied to the current [async context] when the async context itself was polled.
2736
Because `await` expressions are only legal in an async context, there must be some task context available.
2837

38+
r[expr.await.desugar]
2939
## Approximate desugaring
3040

3141
Effectively, an await expression is roughly equivalent to the following non-normative desugaring:

0 commit comments

Comments
 (0)