You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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]
47
52
An expression *evaluates to* a value, and has effects during *evaluation*.
53
+
54
+
r[expr.operands]
48
55
Many expressions contain sub-expressions, called the *operands* of the expression.
56
+
57
+
r[expr.behavior]
49
58
The meaning of each kind of expression dictates several things:
50
59
51
60
* Whether or not to evaluate the operands when evaluating the expression
52
61
* The order in which to evaluate the operands
53
62
* How to combine the operands' values to obtain the value of the expression
54
63
64
+
r[expr.structure]
55
65
In this way, the structure of expressions dictates the structure of execution.
56
66
Blocks are just another kind of expression, so blocks, statements, expressions, and blocks again can recursively nest inside each other to an arbitrary depth.
57
67
58
68
> **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.
59
69
70
+
r[expr.precedence]
60
71
## Expression precedence
61
72
62
73
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
84
95
|`=``+=``-=``*=``/=``%=` <br> `&=` <code>|=</code> `^=``<<=``>>=`| right to left |
85
96
|`return``break` closures ||
86
97
98
+
r[expr.operand-order]
87
99
## Evaluation order of operands
88
100
101
+
r[expr.operand-order.default]
89
102
The following list of expressions all evaluate their operands the same way, as described after the list.
90
103
Other expressions either don't take operands or evaluate them conditionally as described on their respective pages.
91
104
@@ -109,6 +122,7 @@ Other expressions either don't take operands or evaluate them conditionally as d
109
122
* Range expression
110
123
* Return expression
111
124
125
+
r[expr.operand-order.operands-before-primary]
112
126
The operands of these expressions are evaluated prior to applying the effects of the expression.
113
127
Expressions taking multiple operands are evaluated left to right as written in the source code.
114
128
@@ -130,19 +144,28 @@ assert_eq!(
130
144
131
145
> **Note**: Since this is applied recursively, these expressions are also evaluated from innermost to outermost, ignoring siblings until there are no inner subexpressions.
132
146
147
+
r[expr.place-value]
133
148
## Place Expressions and Value Expressions
134
149
150
+
r[expr.place-value.intro]
135
151
Expressions are divided into two main categories: place expressions and value expressions;
136
152
there is also a third, minor category of expressions called assignee expressions.
137
153
Within each expression, operands may likewise occur in either place context or value context.
138
154
The evaluation of an expression depends both on its own category and the context it occurs within.
139
155
156
+
r[expr.place-value.place-memory-location]
140
157
A *place expression* is an expression that represents a memory location.
158
+
159
+
r[expr.place-value.place-expr-kinds]
141
160
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]
142
163
All other expressions are value expressions.
143
164
165
+
r[expr.place-value.value-result]
144
166
A *value expression* is an expression that represents an actual value.
145
167
168
+
r[expr.place-value.place-context]
146
169
The following contexts are *place expression* contexts:
147
170
148
171
* The left operand of a [compound assignment] expression.
@@ -157,6 +180,7 @@ The following contexts are *place expression* contexts:
157
180
158
181
> Note: Historically, place expressions were called *lvalues* and value expressions were called *rvalues*.
159
182
183
+
r[expr.place-value.assignee]
160
184
An *assignee expression* is an expression that appears in the left operand of an [assignment][assign] expression.
161
185
Explicitly, the assignee expressions are:
162
186
@@ -169,29 +193,44 @@ Explicitly, the assignee expressions are:
169
193
fields).
170
194
-[Unit structs][_StructExpression_].
171
195
196
+
r[expr.place-value.parenthesis]
172
197
Arbitrary parenthesisation is permitted inside assignee expressions.
173
198
199
+
r[expr.move]
174
200
### Moved and copied types
175
201
202
+
r[expr.move.intro]
176
203
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]
177
206
If the type of that value implements [`Copy`], then the value will be copied.
207
+
208
+
r[expr.move.requires-sized]
178
209
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]
179
212
Only the following place expressions may be moved out of:
180
213
181
214
*[Variables] which are not currently borrowed.
182
215
*[Temporary values](#temporaries).
183
216
*[Fields][field] of a place expression which can be moved out of and don't implement [`Drop`].
184
217
* The result of [dereferencing][deref] an expression with type [`Box<T>`] and that can also be moved out of.
185
218
219
+
r[expr.move.deinitialization]
186
220
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]
187
223
In all other cases, trying to use a place expression in a value expression context is an error.
188
224
225
+
r[expr.mut]
189
226
### Mutability
190
227
228
+
r[expr.mut.intro]
191
229
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_.
192
230
We call these *mutable place expressions*.
193
231
In contrast, other place expressions are called *immutable place expressions*.
194
232
233
+
r[expr.mut.valid-places]
195
234
The following expressions can be mutable place expression contexts:
196
235
197
236
* Mutable [variables] which are not currently borrowed.
@@ -206,14 +245,17 @@ The following expressions can be mutable place expression contexts:
206
245
*[Array indexing] of a type that implements `IndexMut`:
207
246
this then evaluates the value being indexed, but not the index, in mutable place expression context.
208
247
248
+
r[expr.temporary]
209
249
### Temporaries
210
250
211
251
When using a value expression in most place expression contexts, a temporary unnamed memory location is created and initialized to that value.
212
252
The expression evaluates to that location instead, except if [promoted] to a `static`.
213
253
The [drop scope] of the temporary is usually the end of the enclosing statement.
214
254
255
+
r[expr.implicit-borrow]
215
256
### Implicit Borrows
216
257
258
+
r[expr.implicit-borrow-intro]
217
259
Certain expressions will treat an expression as a place expression by implicitly borrowing it.
218
260
For example, it is possible to compare two unsized [slices][slice] for equality directly, because the `==` operator implicitly borrows its operands:
219
261
@@ -230,6 +272,7 @@ let b: &[i32];
230
272
::std::cmp::PartialEq::eq(&*a, &*b);
231
273
```
232
274
275
+
r[expr.implicit-borrow.application]
233
276
Implicit borrows may be taken in the following expressions:
234
277
235
278
* Left operand in [method-call] expressions.
@@ -240,25 +283,28 @@ Implicit borrows may be taken in the following expressions:
240
283
* Operands of [comparison].
241
284
* Left operands of the [compound assignment].
242
285
286
+
r[expr.overload]
243
287
## Overloading Traits
244
288
245
289
Many of the following operators and expressions can also be overloaded for other types using traits in `std::ops` or `std::cmp`.
246
290
These traits also exist in `core::ops` and `core::cmp` with the same names.
247
291
292
+
r[expr.attr]
248
293
## Expression Attributes
249
294
295
+
r[expr.attr.restriction]
250
296
[Outer attributes][_OuterAttribute_] before an expression are allowed only in a few specific cases:
251
297
252
298
* Before an expression used as a [statement].
253
299
* Elements of [array expressions], [tuple expressions], [call expressions], and tuple-style [struct] expressions.
The first form lists out every value in the array.
21
+
22
+
r[expr.array.array-syntax]
17
23
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]
18
26
This produces an array containing each of these values in the order they are written.
19
27
28
+
r[expr.array.repeat]
20
29
The syntax for the second form is two expressions separated by a semicolon (`;`) enclosed in square brackets.
30
+
31
+
r[expr.array.repeat-operand]
21
32
The expression before the `;` is called the *repeat operand*.
33
+
34
+
r[expr.array.length-operand]
22
35
The expression after the `;` is called the *length operand*.
36
+
37
+
r[expr.array.length-restriction]
23
38
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]
24
41
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.
25
42
That is, `[a; b]` creates an array containing `b` copies of the value of `a`.
43
+
44
+
r[expr.array.repeat-copy]
26
45
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.
27
46
47
+
r[expr.array.repeat-const-item]
28
48
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]
29
51
If that value is `0`, then the constant item is not evaluated at all.
52
+
53
+
r[expr.array.repeat-non-const]
30
54
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.
[Array] and [slice]-typed values can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them.
49
75
When the array is mutable, the resulting [memory location] can be assigned to.
50
76
77
+
r[expr.array.index.trait]
51
78
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.
52
79
Just as with methods, Rust will also insert dereference operations on `a` repeatedly to find an implementation.
53
80
81
+
r[expr.array.index.zero-index]
54
82
Indices are zero-based for arrays and slices.
83
+
84
+
r[expr.array.index.const]
55
85
Array access is a [constant expression], so bounds can be checked at compile-time with a constant index value.
56
86
Otherwise a check will be performed at run-time that will put the thread in a _panicked state_ if it fails.
57
87
@@ -73,6 +103,7 @@ let arr = ["a", "b"];
73
103
arr[10]; // warning: index out of bounds
74
104
```
75
105
106
+
r[expr.array.index.trait-impl]
76
107
The array index expression can be implemented for types other than arrays and slices by implementing the [Index] and [IndexMut] traits.
Copy file name to clipboardexpand all lines: src/expressions/await-expr.md
+10
Original file line number
Diff line number
Diff line change
@@ -1,15 +1,23 @@
1
+
r[expr.await]
1
2
# Await expressions
2
3
4
+
r[expr.await.syntax]
3
5
> **<sup>Syntax</sup>**\
4
6
> _AwaitExpression_ :\
5
7
> [_Expression_]`.``await`
6
8
9
+
r[expr.await.intro]
7
10
An `await` expression is a syntactic construct for suspending a computation
8
11
provided by an implementation of `std::future::IntoFuture` until the given
9
12
future is ready to produce a value.
13
+
14
+
r[expr.await.construct]
10
15
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]
11
18
Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or [`async` block].
12
19
20
+
r[expr.await.effects]
13
21
More specifically, an await expression has the following effect.
14
22
15
23
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.
21
29
22
30
> **Edition differences**: Await expressions are only available beginning with Rust 2018.
23
31
32
+
r[expr.await.task]
24
33
## Task context
25
34
26
35
The task context refers to the [`Context`] which was supplied to the current [async context] when the async context itself was polled.
27
36
Because `await` expressions are only legal in an async context, there must be some task context available.
28
37
38
+
r[expr.await.desugar]
29
39
## Approximate desugaring
30
40
31
41
Effectively, an await expression is roughly equivalent to the following non-normative desugaring:
0 commit comments