]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/expressions/block-expr.md
New upstream version 1.55.0+dfsg1
[rustc.git] / src / doc / reference / src / expressions / block-expr.md
CommitLineData
ea8adc8c
XL
1# Block expressions
2
8faf50e0
XL
3> **<sup>Syntax</sup>**\
4> _BlockExpression_ :\
5> &nbsp;&nbsp; `{`\
6> &nbsp;&nbsp; &nbsp;&nbsp; [_InnerAttribute_]<sup>\*</sup>\
13cf67c4 7> &nbsp;&nbsp; &nbsp;&nbsp; _Statements_<sup>?</sup>\
8faf50e0 8> &nbsp;&nbsp; `}`
b7449926
XL
9>
10> _Statements_ :\
13cf67c4
XL
11> &nbsp;&nbsp; &nbsp;&nbsp; [_Statement_]<sup>\+</sup>\
12> &nbsp;&nbsp; | [_Statement_]<sup>\+</sup> [_ExpressionWithoutBlock_]\
13> &nbsp;&nbsp; | [_ExpressionWithoutBlock_]
14
6a06907d
XL
15A *block expression*, or *block*, is a control flow expression and anonymous namespace scope for items and variable declarations.
16As a control flow expression, a block sequentially executes its component non-item declaration statements and then its final optional expression.
17As 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
cdc7bbd5
XL
19The 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 `}`.
20
21Statements are usually required to be followed by a semicolon, with two exceptions:
22
231. Item declaration statements do not need to be followed by a semicolon.
242. Expression statements usually require a following semicolon except if its outer expression is a flow control expression.
25
6a06907d
XL
26Furthermore, extra semicolons between statements are allowed, but these semicolons do not affect semantics.
27
28When evaluating a block expression, each statement, except for item declaration statements, is executed sequentially.
cdc7bbd5 29Then the final operand is executed, if given.
6a06907d 30
cdc7bbd5 31The type of a block is the type of the final operand, or `()` if the final operand is omitted.
abe05a73 32
b7449926
XL
33```rust
34# fn fn_call() {}
35let _: () = {
36 fn_call();
37};
ea8adc8c 38
b7449926
XL
39let five: i32 = {
40 fn_call();
41 5
42};
ea8adc8c 43
b7449926 44assert_eq!(5, five);
ea8adc8c
XL
45```
46
6a06907d 47> 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.
ea8adc8c 48
cdc7bbd5 49Blocks are always [value expressions] and evaluate the last operand in value expression context.
b7449926 50
cdc7bbd5
XL
51> **Note**: This can be used to force moving a value if really needed.
52> For example, the following example fails on the call to `consume_self` because the struct was moved out of `s` in the block expression.
53>
54> ```rust,compile_fail
55> struct Struct;
56>
57> impl Struct {
58> fn consume_self(self) {}
59> fn borrow_self(&self) {}
60> }
61>
62> fn move_by_block_expression() {
63> let s = Struct;
64>
65> // Move the value out of `s` in the block expression.
66> (&{ s }).borrow_self();
67>
68> // Fails to execute because `s` is moved out of.
69> s.consume_self();
70> }
71> ```
ea8adc8c 72
e1599b0c
XL
73## `async` blocks
74
75> **<sup>Syntax</sup>**\
76> _AsyncBlockExpression_ :\
77> &nbsp;&nbsp; `async` `move`<sup>?</sup> _BlockExpression_
78
cdc7bbd5 79An *async block* is a variant of a block expression which evaluates to a future.
6a06907d 80The final expression of the block, if present, determines the result value of the future.
e1599b0c
XL
81
82Executing an async block is similar to executing a closure expression:
83its immediate effect is to produce and return an anonymous type.
6a06907d
XL
84Whereas 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.
85The actual data format for this type is unspecified.
e1599b0c 86
6a06907d 87> **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.
e1599b0c
XL
88
89> **Edition differences**: Async blocks are only available beginning with Rust 2018.
90
e1599b0c
XL
91### Capture modes
92
6a06907d
XL
93Async blocks capture variables from their environment using the same [capture modes] as closures.
94Like closures, when written `async { .. }` the capture mode for each variable will be inferred from the content of the block.
95`async move { .. }` blocks however will move all referenced variables into the resulting future.
e1599b0c 96
e1599b0c
XL
97### Async context
98
6a06907d
XL
99Because async blocks construct a future, they define an **async context** which can in turn contain [`await` expressions].
100Async contexts are established by async blocks as well as the bodies of async functions, whose semantics are defined in terms of async blocks.
e1599b0c 101
e1599b0c
XL
102### Control-flow operators
103
6a06907d
XL
104Async blocks act like a function boundary, much like closures.
105Therefore, the `?` operator and `return` expressions both affect the output of the future, not the enclosing function or other context.
106That is, `return <expr>` from within a closure will return the result of `<expr>` as the output of the future.
107Similarly, if `<expr>?` propagates an error, that error is propagated as the result of the future.
e1599b0c 108
6a06907d
XL
109Finally, the `break` and `continue` keywords cannot be used to branch out from an async block.
110Therefore the following is illegal:
e1599b0c 111
136023e0 112```rust,compile_fail
e1599b0c
XL
113loop {
114 async move {
115 break; // This would break out of the loop.
116 }
117}
118```
119
ea8adc8c
XL
120## `unsafe` blocks
121
8faf50e0
XL
122> **<sup>Syntax</sup>**\
123> _UnsafeBlockExpression_ :\
abe05a73
XL
124> &nbsp;&nbsp; `unsafe` _BlockExpression_
125
416331ca 126_See [`unsafe` block](../unsafe-blocks.md) for more information on when to use `unsafe`_
ea8adc8c 127
6a06907d
XL
128A block of code can be prefixed with the `unsafe` keyword to permit [unsafe operations].
129Examples:
abe05a73
XL
130
131```rust
132unsafe {
133 let b = [13u8, 17u8];
134 let a = &b[0] as *const u8;
135 assert_eq!(*a, 13);
136 assert_eq!(*a.offset(1), 17);
137}
138
b7449926
XL
139# unsafe fn an_unsafe_fn() -> i32 { 10 }
140let a = unsafe { an_unsafe_fn() };
abe05a73
XL
141```
142
8faf50e0
XL
143## Attributes on block expressions
144
6a06907d 145[Inner attributes] are allowed directly after the opening brace of a block expression in the following situations:
13cf67c4
XL
146
147* [Function] and [method] bodies.
148* Loop bodies ([`loop`], [`while`], [`while let`], and [`for`]).
149* Block expressions used as a [statement].
150* Block expressions as elements of [array expressions], [tuple expressions],
6a06907d 151 [call expressions], and tuple-style [struct] expressions.
13cf67c4
XL
152* A block expression as the tail expression of another block expression.
153<!-- Keep list in sync with expressions.md -->
154
6a06907d 155The attributes that have meaning on a block expression are [`cfg`] and [the lint check attributes].
8faf50e0 156
6a06907d 157For example, this function returns `true` on unix platforms and `false` on other platforms.
8faf50e0
XL
158
159```rust
160fn is_unix_platform() -> bool {
161 #[cfg(unix)] { true }
162 #[cfg(not(unix))] { false }
163}
164```
165
416331ca
XL
166[_ExpressionWithoutBlock_]: ../expressions.md
167[_InnerAttribute_]: ../attributes.md
168[_Statement_]: ../statements.md
cdc7bbd5 169[`await` expressions]: await-expr.md
416331ca
XL
170[`cfg`]: ../conditional-compilation.md
171[`for`]: loop-expr.md#iterator-loops
172[`loop`]: loop-expr.md#infinite-loops
cdc7bbd5
XL
173[`std::ops::Fn`]: ../../std/ops/trait.Fn.html
174[`std::future::Future`]: ../../std/future/trait.Future.html
416331ca
XL
175[`while let`]: loop-expr.md#predicate-pattern-loops
176[`while`]: loop-expr.md#predicate-loops
177[array expressions]: array-expr.md
178[call expressions]: call-expr.md
cdc7bbd5 179[capture modes]: ../types/closure.md#capture-modes
416331ca
XL
180[function]: ../items/functions.md
181[inner attributes]: ../attributes.md
182[method]: ../items/associated-items.md#methods
cdc7bbd5
XL
183[mutable reference]: ../types/pointer.md#mutables-references-
184[shared references]: ../types/pointer.md#shared-references-
416331ca
XL
185[statement]: ../statements.md
186[statements]: ../statements.md
187[struct]: struct-expr.md
188[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
189[tuple expressions]: tuple-expr.md
190[unsafe operations]: ../unsafety.md
191[value expressions]: ../expressions.md#place-expressions-and-value-expressions