]> git.proxmox.com Git - rustc.git/blame - src/doc/reference/src/expressions/block-expr.md
New upstream version 1.38.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
15A *block expression*, or *block*, is a control flow expression and anonymous
b7449926
XL
16namespace scope for items and variable declarations. As a control flow
17expression, a block sequentially executes its component non-item declaration
18statements and then its final optional expression. As an anonymous namespace
19scope, item declarations are only in scope inside the block itself and variables
20declared by `let` statements are in scope from the next statement until the end
21of the block.
22
23Blocks are written as `{`, then any [inner attributes], then [statements],
24then an optional expression, and finally a `}`. Statements are usually required
25to be followed a semicolon, with two exceptions. Item declaration statements do
26not need to be followed by a semicolon. Expression statements usually require
27a following semicolon except if its outer expression is a flow control
28expression. Furthermore, extra semicolons between statements are allowed, but
29these semicolons do not affect semantics.
30
31> Note: The semicolon following a statement is not a part of the statement
32> itself. They are invalid when using the `stmt` macro matcher.
33
34When evaluating a block expression, each statement, except for item declaration
35statements, is executed sequentially. Then the final expression is executed,
36if given.
37
38The type of a block is the type of the final expression, or `()` if the final
39expression is omitted.
abe05a73 40
b7449926
XL
41```rust
42# fn fn_call() {}
43let _: () = {
44 fn_call();
45};
ea8adc8c 46
b7449926
XL
47let five: i32 = {
48 fn_call();
49 5
50};
ea8adc8c 51
b7449926 52assert_eq!(5, five);
ea8adc8c
XL
53```
54
b7449926
XL
55> Note: As a control flow expression, if a block expression is the outer
56> expression of an expression statement, the expected type is `()` unless it
57> is followed immediately by a semicolon.
ea8adc8c 58
13cf67c4 59Blocks are always [value expressions] and evaluate the last expression in
b7449926
XL
60value expression context. This can be used to force moving a value if really
61needed. For example, the following example fails on the call to `consume_self`
62because the struct was moved out of `s` in the block expression.
ea8adc8c 63
b7449926
XL
64```rust,compile_fail
65struct Struct;
ea8adc8c 66
b7449926
XL
67impl Struct {
68 fn consume_self(self) {}
69 fn borrow_self(&self) {}
70}
71
72fn move_by_block_expression() {
73 let s = Struct;
74
13cf67c4 75 // Move the value out of `s` in the block expression.
b7449926
XL
76 (&{ s }).borrow_self();
77
78 // Fails to execute because `s` is moved out of.
79 s.consume_self();
80}
81```
ea8adc8c
XL
82
83## `unsafe` blocks
84
8faf50e0
XL
85> **<sup>Syntax</sup>**\
86> _UnsafeBlockExpression_ :\
abe05a73
XL
87> &nbsp;&nbsp; `unsafe` _BlockExpression_
88
416331ca 89_See [`unsafe` block](../unsafe-blocks.md) for more information on when to use `unsafe`_
ea8adc8c 90
b7449926
XL
91A block of code can be prefixed with the `unsafe` keyword to permit [unsafe
92operations]. Examples:
abe05a73
XL
93
94```rust
95unsafe {
96 let b = [13u8, 17u8];
97 let a = &b[0] as *const u8;
98 assert_eq!(*a, 13);
99 assert_eq!(*a.offset(1), 17);
100}
101
b7449926
XL
102# unsafe fn an_unsafe_fn() -> i32 { 10 }
103let a = unsafe { an_unsafe_fn() };
abe05a73
XL
104```
105
8faf50e0
XL
106## Attributes on block expressions
107
13cf67c4
XL
108[Inner attributes] are allowed directly after the opening brace of a block
109expression in the following situations:
110
111* [Function] and [method] bodies.
112* Loop bodies ([`loop`], [`while`], [`while let`], and [`for`]).
113* Block expressions used as a [statement].
114* Block expressions as elements of [array expressions], [tuple expressions],
115 [call expressions], tuple-style [struct] and [enum variant] expressions.
116* A block expression as the tail expression of another block expression.
117<!-- Keep list in sync with expressions.md -->
118
119The attributes that have meaning on a block expression are [`cfg`] and [the
120lint check attributes].
8faf50e0
XL
121
122For example, this function returns `true` on unix platforms and `false` on other
123platforms.
124
125```rust
126fn is_unix_platform() -> bool {
127 #[cfg(unix)] { true }
128 #[cfg(not(unix))] { false }
129}
130```
131
416331ca
XL
132[_ExpressionWithoutBlock_]: ../expressions.md
133[_InnerAttribute_]: ../attributes.md
134[_Statement_]: ../statements.md
135[`cfg`]: ../conditional-compilation.md
136[`for`]: loop-expr.md#iterator-loops
137[`loop`]: loop-expr.md#infinite-loops
138[`while let`]: loop-expr.md#predicate-pattern-loops
139[`while`]: loop-expr.md#predicate-loops
140[array expressions]: array-expr.md
141[call expressions]: call-expr.md
142[enum variant]: enum-variant-expr.md
143[function]: ../items/functions.md
144[inner attributes]: ../attributes.md
145[method]: ../items/associated-items.md#methods
146[statement]: ../statements.md
147[statements]: ../statements.md
148[struct]: struct-expr.md
149[the lint check attributes]: ../attributes/diagnostics.md#lint-check-attributes
150[tuple expressions]: tuple-expr.md
151[unsafe operations]: ../unsafety.md
152[value expressions]: ../expressions.md#place-expressions-and-value-expressions