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
The first form lists out every value in the array.
22
+
23
+
r[expr.array.array-syntax]
17
24
The syntax for this form is a comma-separated list of expressions of uniform type enclosed in square brackets.
25
+
26
+
r[expr.array.array-behaviour]
18
27
This produces an array containing each of these values in the order they are written.
19
28
29
+
r[expr.array.repeat]
20
30
The syntax for the second form is two expressions separated by a semicolon (`;`) enclosed in square brackets.
31
+
32
+
r[expr.array.repeat-operand]
21
33
The expression before the `;` is called the *repeat operand*.
34
+
35
+
r[expr.array.length-operand]
22
36
The expression after the `;` is called the *length operand*.
37
+
38
+
r[expr.array.length-restriction]
23
39
It must have type `usize` and be a [constant expression], such as a [literal] or a [constant item].
40
+
41
+
r[expr.array.repeat-behaviour]
24
42
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
43
That is, `[a; b]` creates an array containing `b` copies of the value of `a`.
44
+
45
+
r[expr.array.repeat-copy]
26
46
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
47
48
+
r[expr.array.repeat-const-item]
28
49
When the repeat operand is a constant item, it is evaluated the length operand's value times.
50
+
51
+
r[expr.array.repeat-evaluation-zero]
29
52
If that value is `0`, then the constant item is not evaluated at all.
53
+
54
+
r[expr.array.repeat-non-const]
30
55
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
77
When the array is mutable, the resulting [memory location] can be assigned to.
50
78
79
+
r[expr.array.index.trait]
51
80
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
81
Just as with methods, Rust will also insert dereference operations on `a` repeatedly to find an implementation.
53
82
83
+
r[expr.array.index.zero-index]
54
84
Indices are zero-based for arrays and slices.
85
+
86
+
r[expr.array.index.const]
55
87
Array access is a [constant expression], so bounds can be checked at compile-time with a constant index value.
56
88
Otherwise a check will be performed at run-time that will put the thread in a _panicked state_ if it fails.
57
89
@@ -73,6 +105,7 @@ let arr = ["a", "b"];
73
105
arr[10]; // warning: index out of bounds
74
106
```
75
107
108
+
r[expr.array.index.trait-impl]
76
109
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
+13Lines changed: 13 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -1,15 +1,24 @@
1
1
# Await expressions
2
2
3
+
r[expr.await]
4
+
5
+
r[expr.await.syntax]
3
6
> **<sup>Syntax</sup>**\
4
7
> _AwaitExpression_ :\
5
8
> [_Expression_]`.``await`
6
9
10
+
r[expr.await.intro]
7
11
An `await` expression is a syntactic construct for suspending a computation
8
12
provided by an implementation of `std::future::IntoFuture` until the given
9
13
future is ready to produce a value.
14
+
15
+
r[expr.await.construct]
10
16
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.
17
+
18
+
r[expr.await.constraints]
11
19
Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or [`async` block].
12
20
21
+
r[expr.await.effects]
13
22
More specifically, an await expression has the following effect.
14
23
15
24
1. Create a future by calling [`IntoFuture::into_future`] on the future operand.
@@ -23,11 +32,15 @@ More specifically, an await expression has the following effect.
23
32
24
33
## Task context
25
34
35
+
r[expr.await.task]
36
+
26
37
The task context refers to the [`Context`] which was supplied to the current [async context] when the async context itself was polled.
27
38
Because `await` expressions are only legal in an async context, there must be some task context available.
28
39
29
40
## Approximate desugaring
30
41
42
+
r[expr.await.desugar]
43
+
31
44
Effectively, an await expression is roughly equivalent to the following non-normative desugaring:
A *block expression*, or *block*, is a control flow expression and anonymous namespace scope for items and variable declarations.
20
+
21
+
r[expr.block.sequential-evaluation]
16
22
As a control flow expression, a block sequentially executes its component non-item declaration statements and then its final optional expression.
23
+
24
+
r[expr.block.namepsace]
17
25
As an anonymous namespace scope, item declarations are only in scope inside the block itself and variables declared by `let` statements are in scope from the next statement until the end of the block.
18
26
See the [scopes] chapter for more details.
19
27
28
+
r[expr.block.inner-attributes]
20
29
The syntax for a block is `{`, then any [inner attributes], then any number of [statements], then an optional expression, called the final operand, and finally a `}`.
21
30
31
+
r[expr.block.statements]
22
32
Statements are usually required to be followed by a semicolon, with two exceptions:
23
33
24
34
1. Item declaration statements do not need to be followed by a semicolon.
25
35
2. Expression statements usually require a following semicolon except if its outer expression is a flow control expression.
26
36
37
+
r[expr.block.null-statement]
27
38
Furthermore, extra semicolons between statements are allowed, but these semicolons do not affect semantics.
28
39
40
+
r[expr.block.evaluation]
29
41
When evaluating a block expression, each statement, except for item declaration statements, is executed sequentially.
42
+
43
+
r[expr.block.result]
30
44
Then the final operand is executed, if given.
31
45
46
+
r[expr.block.type]
32
47
The type of a block is the type of the final operand, or `()` if the final operand is omitted.
33
48
34
49
```rust
@@ -47,6 +62,7 @@ assert_eq!(5, five);
47
62
48
63
> Note: As a control flow expression, if a block expression is the outer expression of an expression statement, the expected type is `()` unless it is followed immediately by a semicolon.
49
64
65
+
r[expr.block.value]
50
66
Blocks are always [value expressions] and evaluate the last operand in value expression context.
51
67
52
68
> **Note**: This can be used to force moving a value if really needed.
@@ -73,16 +89,27 @@ Blocks are always [value expressions] and evaluate the last operand in value exp
An *async block* is a variant of a block expression which evaluates to a future.
101
+
102
+
r[expr.block.async.future-result]
81
103
The final expression of the block, if present, determines the result value of the future.
82
104
105
+
r[expr.block.async.anonymous-type]
83
106
Executing an async block is similar to executing a closure expression:
84
107
its immediate effect is to produce and return an anonymous type.
108
+
109
+
r[expr.block.async.future]
85
110
Whereas closures return a type that implements one or more of the [`std::ops::Fn`] traits, however, the type returned for an async block implements the [`std::future::Future`] trait.
111
+
112
+
r[expr.block.async.layout-unspecified]
86
113
The actual data format for this type is unspecified.
87
114
88
115
> **Note:** The future type that rustc generates is roughly equivalent to an enum with one variant per `await` point, where each variant stores the data needed to resume from its corresponding point.
@@ -91,22 +118,32 @@ The actual data format for this type is unspecified.
91
118
92
119
### Capture modes
93
120
121
+
r[expr.block.async.capture]
122
+
94
123
Async blocks capture variables from their environment using the same [capture modes] as closures.
95
124
Like closures, when written `async { .. }` the capture mode for each variable will be inferred from the content of the block.
96
125
`async move { .. }` blocks however will move all referenced variables into the resulting future.
97
126
98
127
### Async context
99
128
129
+
r[expr.block.async.context]
130
+
100
131
Because async blocks construct a future, they define an **async context** which can in turn contain [`await` expressions].
101
132
Async contexts are established by async blocks as well as the bodies of async functions, whose semantics are defined in terms of async blocks.
102
133
103
134
### Control-flow operators
104
135
136
+
r[expr.block.async.function]
137
+
138
+
r[expr.block.async.function.intro]
105
139
Async blocks act like a function boundary, much like closures.
140
+
141
+
r[expr.block.async.function.return-try]
106
142
Therefore, the `?` operator and `return` expressions both affect the output of the future, not the enclosing function or other context.
107
143
That is, `return <expr>` from within an async block will return the result of `<expr>` as the output of the future.
108
144
Similarly, if `<expr>?` propagates an error, that error is propagated as the result of the future.
109
145
146
+
r[expr.block.async.function.control-flow]
110
147
Finally, the `break` and `continue` keywords cannot be used to branch out from an async block.
111
148
Therefore the following is illegal:
112
149
@@ -120,15 +157,21 @@ loop {
120
157
121
158
## `const` blocks
122
159
160
+
r[expr.block.const]
161
+
162
+
r[expr.block.const.syntax]
123
163
> **<sup>Syntax</sup>**\
124
164
> _ConstBlockExpression_ :\
125
165
> `const`_BlockExpression_
126
166
167
+
r[expr.block.const.intro]
127
168
A *const block* is a variant of a block expression whose body evaluates at compile-time instead of at runtime.
128
169
170
+
r[expr.block.const.context]
129
171
Const blocks allows you to define a constant value without having to define new [constant items], and thus they are also sometimes referred as *inline consts*.
130
172
It also supports type inference so there is no need to specify the type, unlike [constant items].
131
173
174
+
r[expr.block.const.generic-params]
132
175
Const blocks have the ability to reference generic parameters in scope, unlike [free][free item] constant items.
133
176
They are desugared to constant items with generic parameters in scope (similar to associated constants, but without a trait or type they are associated with).
134
177
For example, this code:
@@ -153,6 +196,8 @@ fn foo<T>() -> usize {
153
196
}
154
197
```
155
198
199
+
r[expr.block.const.evaluation]
200
+
156
201
If the const block expression is executed at runtime, then the constant is guaranteed to be evaluated, even if its return value is ignored:
157
202
158
203
```rust
@@ -166,6 +211,8 @@ fn foo<T>() -> usize {
166
211
}
167
212
```
168
213
214
+
r[expr.block.const.not-executed]
215
+
169
216
If the const block expression is not executed at runtime, it may or may not be evaluated:
170
217
```rust,compile_fail
171
218
if false {
@@ -176,6 +223,8 @@ if false {
176
223
177
224
## `unsafe` blocks
178
225
226
+
r[expr.block.unsafe]
227
+
179
228
> **<sup>Syntax</sup>**\
180
229
> _UnsafeBlockExpression_ :\
181
230
> `unsafe`_BlockExpression_
@@ -199,10 +248,15 @@ let a = unsafe { an_unsafe_fn() };
199
248
200
249
## Labelled block expressions
201
250
251
+
r[expr.block.label]
252
+
202
253
Labelled block expressions are documented in the [Loops and other breakable expressions] section.
203
254
204
255
## Attributes on block expressions
205
256
257
+
r[expr.block.attributes]
258
+
259
+
r[expr.block.attributes.inner-attributes]
206
260
[Inner attributes] are allowed directly after the opening brace of a block expression in the following situations:
207
261
208
262
*[Function] and [method] bodies.
@@ -213,6 +267,7 @@ Labelled block expressions are documented in the [Loops and other breakable expr
213
267
* A block expression as the tail expression of another block expression.
214
268
<!-- Keep list in sync with expressions.md -->
215
269
270
+
r[expr.block.attributes.valid]
216
271
The attributes that have meaning on a block expression are [`cfg`] and [the lint check attributes].
217
272
218
273
For example, this function returns `true` on unix platforms and `false` on other platforms.
0 commit comments