4
4
> _ BlockExpression_ :\
5
5
>   ;  ; ` { ` \
6
6
>   ;  ;   ;  ; [ _ InnerAttribute_ ] <sup >\* </sup >\
7
- >   ;  ;   ;  ; [ _ Statement _ ] <sup >\* </sup >\
7
+ >   ;  ;   ;  ; _ Statements _ <sup >\* </sup >\
8
8
>   ;  ;   ;  ; [ _ Expression_ ] <sup >?</sup >\
9
9
>   ;  ; ` } `
10
+ >
11
+ > _ Statements_ :\
12
+ >   ;  ; ( ` ; ` \
13
+ >   ;  ; | [ _ ItemDeclaration_ ] \
14
+ >   ;  ; | [ _ LetStatement_ ] ;\
15
+ >   ;  ; | [ _ NonControlFlowExpressionStatement_ ] [ expression statement ] ;\
16
+ >   ;  ; | [ _ FlowControlExpressionStatement_ ] [ expression statement ] ;<sup >?</sup >\
17
+ >   ;  ; )<sup >\* </sup >
18
+
19
+ A * block expression* , or * block* , is a control flow expression and anonymouse
20
+ namespace scope for items and variable declarations. As a control flow
21
+ expression, a block sequentially executes its component non-item declaration
22
+ statements and then its final optional expression. As an anonymous namespace
23
+ scope, item declarations are only in scope inside the block itself and variables
24
+ declared by ` let ` statements are in scope from the next statement until the end
25
+ of the block.
26
+
27
+ Blocks are written as ` { ` , then any [ inner attributes] , then [ statements] ,
28
+ then an optional expression, and finally a ` } ` . Statements are usually required
29
+ to be followed a semicolon, with two exceptions. Item declaration statements do
30
+ not need to be followed by a semicolon. Expression statements usually require
31
+ a following semicolon except if its outer expression is a flow control
32
+ expression. Furthermore, extra semicolons between statements are allowed, but
33
+ these semicolons do not affect semantics.
34
+
35
+ > Note: The semicolon following a statement is not a part of the statement
36
+ > itself. They are invalid when using the ` stmt ` macro matcher.
37
+
38
+ When evaluating a block expression, each statement, except for item declaration
39
+ statements, is executed sequentially. Then the final expression is executed,
40
+ if given.
41
+
42
+ The type of a block is the type of the final expression, or ` () ` if the final
43
+ expression is omitted.
10
44
11
- A _ block expression _ is similar to a module in terms of the declarations that
12
- are possible, but can also contain [ statements ] and end with
13
- an [ expression ] . Each block conceptually introduces a new namespace scope. Use
14
- items can bring new names into scopes and declared items are in scope for only
15
- the block itself.
45
+ ``` rust
46
+ # fn fn_call () {}
47
+ let _ : () = {
48
+ fn_call ();
49
+ };
16
50
17
- A block will execute each statement sequentially, and then execute the
18
- expression, if given. If the block doesn't end in an expression, its value is
19
- ` () ` :
51
+ let five : i32 = {
52
+ fn_call ();
53
+ 5
54
+ };
20
55
21
- ``` rust
22
- let x : () = { println! (" Hello." ); };
56
+ assert_eq! (5 , five );
23
57
```
24
58
25
- If it ends in an expression, its value and type are that of the expression:
59
+ > Note: As a control flow expression, if a block expression is the outer
60
+ > expression of an expression statement, the expected type is ` () ` unless it
61
+ > is followed immediately by a semicolon.
26
62
27
- ``` rust
28
- let x : i32 = { println! (" Hello." ); 5 };
63
+ Blocks are always [ value expressions] and evaluate the last expression in
64
+ value expression context. This can be used to force moving a value if really
65
+ needed. For example, the following example fails on the call to ` consume_self `
66
+ because the struct was moved out of ` s ` in the block expression.
29
67
30
- assert_eq! ( 5 , x );
31
- ```
68
+ ``` rust,compile_fail
69
+ struct Struct;
32
70
33
- Blocks are always [ value expressions] and evaluate the last expression in
34
- value expression context. This can be used to force moving a value if really
35
- needed.
71
+ impl Struct {
72
+ fn consume_self(self) {}
73
+ fn borrow_self(&self) {}
74
+ }
75
+
76
+ fn move_by_block_expression() {
77
+ let s = Struct;
78
+
79
+ // Move the value out of `s` in the block expreesion.
80
+ (&{ s }).borrow_self();
81
+
82
+ // Fails to execute because `s` is moved out of.
83
+ s.consume_self();
84
+ }
85
+ ```
36
86
37
87
## ` unsafe ` blocks
38
88
@@ -42,8 +92,8 @@ needed.
42
92
43
93
_ See [ ` unsafe ` block] ( unsafe-blocks.html ) for more information on when to use ` unsafe ` _
44
94
45
- A block of code can be prefixed with the ` unsafe ` keyword, to permit calling
46
- ` unsafe ` functions or dereferencing raw pointers within a safe function . Examples:
95
+ A block of code can be prefixed with the ` unsafe ` keyword to permit [ unsafe
96
+ operations ] . Examples:
47
97
48
98
``` rust
49
99
unsafe {
@@ -53,8 +103,8 @@ unsafe {
53
103
assert_eq! (* a . offset (1 ), 17 );
54
104
}
55
105
56
- # unsafe fn f () -> i32 { 10 }
57
- let a = unsafe { f () };
106
+ # unsafe fn an_unsafe_fn () -> i32 { 10 }
107
+ let a = unsafe { an_unsafe_fn () };
58
108
```
59
109
60
110
## Attributes on block expressions
@@ -76,7 +126,9 @@ fn is_unix_platform() -> bool {
76
126
```
77
127
78
128
[ _InnerAttribute_ ] : attributes.html
79
- [ _Statement_ ] : statements.html
129
+ [ _ItemDeclaration_ ] : items.html
130
+ [ _LetStatement_ ] : statements.html#let-statements
131
+ [ expression statement ] : statements.html#expression-statements
80
132
[ _Expression_ ] : expressions.html
81
133
[ expression ] : expressions.html
82
134
[ statements ] : statements.html
@@ -86,3 +138,4 @@ fn is_unix_platform() -> bool {
86
138
[ expression statement ] : statements.html#expression-statements
87
139
[ `cfg` ] : attributes.html#conditional-compilation
88
140
[ the lint check attributes ] : attributes.html#lint-check-attributes
141
+ [ unsafe operations ] : unsafety.html
0 commit comments