Skip to content

Commit 9446598

Browse files
chorman0773ehuss
authored andcommitted
Add identifier syntax to array-expr through block-expr
1 parent 9134fe5 commit 9446598

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

src/expressions/array-expr.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Array and array index expressions
22

3+
r[expr.array]
4+
35
## Array expressions
46

7+
r[expr.array.syntax]
58
> **<sup>Syntax</sup>**\
69
> _ArrayExpression_ :\
710
> &nbsp;&nbsp; `[` _ArrayElements_<sup>?</sup> `]`
@@ -10,23 +13,45 @@
1013
> &nbsp;&nbsp; &nbsp;&nbsp; [_Expression_] ( `,` [_Expression_] )<sup>\*</sup> `,`<sup>?</sup>\
1114
> &nbsp;&nbsp; | [_Expression_] `;` [_Expression_]
1215
16+
r[expr.array.constructor]
1317
*Array expressions* construct [arrays][array].
1418
Array expressions come in two forms.
1519

20+
r[expr.array.array]
1621
The first form lists out every value in the array.
22+
23+
r[expr.array.array-syntax]
1724
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]
1827
This produces an array containing each of these values in the order they are written.
1928

29+
r[expr.array.repeat]
2030
The syntax for the second form is two expressions separated by a semicolon (`;`) enclosed in square brackets.
31+
32+
r[expr.array.repeat-operand]
2133
The expression before the `;` is called the *repeat operand*.
34+
35+
r[expr.array.length-operand]
2236
The expression after the `;` is called the *length operand*.
37+
38+
r[expr.array.length-restriction]
2339
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]
2442
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.
2543
That is, `[a; b]` creates an array containing `b` copies of the value of `a`.
44+
45+
r[expr.array.repeat-copy]
2646
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.
2747

48+
r[expr.array.repeat-const-item]
2849
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]
2952
If that value is `0`, then the constant item is not evaluated at all.
53+
54+
r[expr.array.repeat-non-const]
3055
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.
3156

3257
```rust
@@ -41,17 +66,24 @@ const EMPTY: Vec<i32> = Vec::new();
4166

4267
## Array and slice indexing expressions
4368

69+
r[expr.array.index]
70+
4471
> **<sup>Syntax</sup>**\
4572
> _IndexExpression_ :\
4673
> &nbsp;&nbsp; [_Expression_] `[` [_Expression_] `]`
4774
75+
r[expr.array.index.array]
4876
[Array] and [slice]-typed values can be indexed by writing a square-bracket-enclosed expression of type `usize` (the index) after them.
4977
When the array is mutable, the resulting [memory location] can be assigned to.
5078

79+
r[expr.array.index.trait]
5180
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.
5281
Just as with methods, Rust will also insert dereference operations on `a` repeatedly to find an implementation.
5382

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

@@ -73,6 +105,7 @@ let arr = ["a", "b"];
73105
arr[10]; // warning: index out of bounds
74106
```
75107

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

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

src/expressions/await-expr.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
# Await expressions
22

3+
r[expr.await]
4+
5+
r[expr.await.syntax]
36
> **<sup>Syntax</sup>**\
47
> _AwaitExpression_ :\
58
> &nbsp;&nbsp; [_Expression_] `.` `await`
69
10+
r[expr.await.intro]
711
An `await` expression is a syntactic construct for suspending a computation
812
provided by an implementation of `std::future::IntoFuture` until the given
913
future is ready to produce a value.
14+
15+
r[expr.await.construct]
1016
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]
1119
Await expressions are legal only within an [async context], like an [`async fn`], [`async` closure], or [`async` block].
1220

21+
r[expr.await.effects]
1322
More specifically, an await expression has the following effect.
1423

1524
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.
2332
2433
## Task context
2534

35+
r[expr.await.task]
36+
2637
The task context refers to the [`Context`] which was supplied to the current [async context] when the async context itself was polled.
2738
Because `await` expressions are only legal in an async context, there must be some task context available.
2839

2940
## Approximate desugaring
3041

42+
r[expr.await.desugar]
43+
3144
Effectively, an await expression is roughly equivalent to the following non-normative desugaring:
3245

3346
<!-- ignore: example expansion -->

src/expressions/block-expr.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Block expressions
22

3+
r[expr.block]
4+
5+
r[expr.block.syntax]
36
> **<sup>Syntax</sup>**\
47
> _BlockExpression_ :\
58
> &nbsp;&nbsp; `{`\
@@ -12,23 +15,35 @@
1215
> &nbsp;&nbsp; | [_Statement_]<sup>\+</sup> [_ExpressionWithoutBlock_]\
1316
> &nbsp;&nbsp; | [_ExpressionWithoutBlock_]
1417
18+
r[expr.block.intro]
1519
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]
1622
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]
1725
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.
1826
See the [scopes] chapter for more details.
1927

28+
r[expr.block.inner-attributes]
2029
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 `}`.
2130

31+
r[expr.block.statements]
2232
Statements are usually required to be followed by a semicolon, with two exceptions:
2333

2434
1. Item declaration statements do not need to be followed by a semicolon.
2535
2. Expression statements usually require a following semicolon except if its outer expression is a flow control expression.
2636

37+
r[expr.block.null-statement]
2738
Furthermore, extra semicolons between statements are allowed, but these semicolons do not affect semantics.
2839

40+
r[expr.block.evaluation]
2941
When evaluating a block expression, each statement, except for item declaration statements, is executed sequentially.
42+
43+
r[expr.block.result]
3044
Then the final operand is executed, if given.
3145

46+
r[expr.block.type]
3247
The type of a block is the type of the final operand, or `()` if the final operand is omitted.
3348

3449
```rust
@@ -47,6 +62,7 @@ assert_eq!(5, five);
4762

4863
> 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.
4964
65+
r[expr.block.value]
5066
Blocks are always [value expressions] and evaluate the last operand in value expression context.
5167

5268
> **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
7389
7490
## `async` blocks
7591
92+
r[expr.block.async]
93+
94+
r[expr.block.async.syntax]
7695
> **<sup>Syntax</sup>**\
7796
> _AsyncBlockExpression_ :\
7897
> &nbsp;&nbsp; `async` `move`<sup>?</sup> _BlockExpression_
7998
99+
r[expr.block.async.intro]
80100
An *async block* is a variant of a block expression which evaluates to a future.
101+
102+
r[expr.block.async.future-result]
81103
The final expression of the block, if present, determines the result value of the future.
82104
105+
r[expr.block.async.anonymous-type]
83106
Executing an async block is similar to executing a closure expression:
84107
its immediate effect is to produce and return an anonymous type.
108+
109+
r[expr.block.async.future]
85110
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]
86113
The actual data format for this type is unspecified.
87114
88115
> **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.
91118
92119
### Capture modes
93120
121+
r[expr.block.async.capture]
122+
94123
Async blocks capture variables from their environment using the same [capture modes] as closures.
95124
Like closures, when written `async { .. }` the capture mode for each variable will be inferred from the content of the block.
96125
`async move { .. }` blocks however will move all referenced variables into the resulting future.
97126
98127
### Async context
99128
129+
r[expr.block.async.context]
130+
100131
Because async blocks construct a future, they define an **async context** which can in turn contain [`await` expressions].
101132
Async contexts are established by async blocks as well as the bodies of async functions, whose semantics are defined in terms of async blocks.
102133
103134
### Control-flow operators
104135
136+
r[expr.block.async.function]
137+
138+
r[expr.block.async.function.intro]
105139
Async blocks act like a function boundary, much like closures.
140+
141+
r[expr.block.async.function.return-try]
106142
Therefore, the `?` operator and `return` expressions both affect the output of the future, not the enclosing function or other context.
107143
That is, `return <expr>` from within an async block will return the result of `<expr>` as the output of the future.
108144
Similarly, if `<expr>?` propagates an error, that error is propagated as the result of the future.
109145
146+
r[expr.block.async.function.control-flow]
110147
Finally, the `break` and `continue` keywords cannot be used to branch out from an async block.
111148
Therefore the following is illegal:
112149
@@ -120,15 +157,21 @@ loop {
120157
121158
## `const` blocks
122159

160+
r[expr.block.const]
161+
162+
r[expr.block.const.syntax]
123163
> **<sup>Syntax</sup>**\
124164
> _ConstBlockExpression_ :\
125165
> &nbsp;&nbsp; `const` _BlockExpression_
126166
167+
r[expr.block.const.intro]
127168
A *const block* is a variant of a block expression whose body evaluates at compile-time instead of at runtime.
128169

170+
r[expr.block.const.context]
129171
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*.
130172
It also supports type inference so there is no need to specify the type, unlike [constant items].
131173

174+
r[expr.block.const.generic-params]
132175
Const blocks have the ability to reference generic parameters in scope, unlike [free][free item] constant items.
133176
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).
134177
For example, this code:
@@ -153,6 +196,8 @@ fn foo<T>() -> usize {
153196
}
154197
```
155198

199+
r[expr.block.const.evaluation]
200+
156201
If the const block expression is executed at runtime, then the constant is guaranteed to be evaluated, even if its return value is ignored:
157202

158203
```rust
@@ -166,6 +211,8 @@ fn foo<T>() -> usize {
166211
}
167212
```
168213

214+
r[expr.block.const.not-executed]
215+
169216
If the const block expression is not executed at runtime, it may or may not be evaluated:
170217
```rust,compile_fail
171218
if false {
@@ -176,6 +223,8 @@ if false {
176223

177224
## `unsafe` blocks
178225

226+
r[expr.block.unsafe]
227+
179228
> **<sup>Syntax</sup>**\
180229
> _UnsafeBlockExpression_ :\
181230
> &nbsp;&nbsp; `unsafe` _BlockExpression_
@@ -199,10 +248,15 @@ let a = unsafe { an_unsafe_fn() };
199248

200249
## Labelled block expressions
201250

251+
r[expr.block.label]
252+
202253
Labelled block expressions are documented in the [Loops and other breakable expressions] section.
203254

204255
## Attributes on block expressions
205256

257+
r[expr.block.attributes]
258+
259+
r[expr.block.attributes.inner-attributes]
206260
[Inner attributes] are allowed directly after the opening brace of a block expression in the following situations:
207261

208262
* [Function] and [method] bodies.
@@ -213,6 +267,7 @@ Labelled block expressions are documented in the [Loops and other breakable expr
213267
* A block expression as the tail expression of another block expression.
214268
<!-- Keep list in sync with expressions.md -->
215269

270+
r[expr.block.attributes.valid]
216271
The attributes that have meaning on a block expression are [`cfg`] and [the lint check attributes].
217272

218273
For example, this function returns `true` on unix platforms and `false` on other platforms.

0 commit comments

Comments
 (0)