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