]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/statements.md
New upstream version 1.54.0+dfsg1
[rustc.git] / src / doc / reference / src / statements.md
1 # Statements
2
3 > **<sup>Syntax</sup>**\
4 > _Statement_ :\
5 > &nbsp;&nbsp; &nbsp;&nbsp; `;`\
6 > &nbsp;&nbsp; | [_Item_]\
7 > &nbsp;&nbsp; | [_LetStatement_]\
8 > &nbsp;&nbsp; | [_ExpressionStatement_]\
9 > &nbsp;&nbsp; | [_MacroInvocationSemi_]
10
11
12 A *statement* is a component of a [block], which is in turn a component of an
13 outer [expression] or [function].
14
15 Rust has two kinds of statement: [declaration
16 statements](#declaration-statements) and [expression
17 statements](#expression-statements).
18
19 ## Declaration statements
20
21 A *declaration statement* is one that introduces one or more *names* into the
22 enclosing statement block. The declared names may denote new variables or new
23 [items][item].
24
25 The two kinds of declaration statements are item declarations and `let`
26 statements.
27
28 ### Item declarations
29
30 An *item declaration statement* has a syntactic form identical to an
31 [item declaration][item] within a [module]. Declaring an item within a statement
32 block restricts its scope to the block containing the statement. The item is not
33 given a [canonical path] nor are any sub-items it may declare. The exception to
34 this is that associated items defined by [implementations] are still accessible
35 in outer scopes as long as the item and, if applicable, trait are accessible.
36 It is otherwise identical in meaning to declaring the item inside a module.
37
38 There is no implicit capture of the containing function's generic parameters,
39 parameters, and local variables. For example, `inner` may not access
40 `outer_var`.
41
42 ```rust
43 fn outer() {
44 let outer_var = true;
45
46 fn inner() { /* outer_var is not in scope here */ }
47
48 inner();
49 }
50 ```
51
52 ### `let` statements
53
54 > **<sup>Syntax</sup>**\
55 > _LetStatement_ :\
56 > &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> `let` [_PatternNoTopAlt_]
57 > ( `:` [_Type_] )<sup>?</sup> (`=` [_Expression_] )<sup>?</sup> `;`
58
59 A *`let` statement* introduces a new set of [variables], given by an
60 irrefutable [pattern]. The pattern is followed optionally by a type
61 annotation and then optionally by an initializer expression. When no
62 type annotation is given, the compiler will infer the type, or signal
63 an error if insufficient type information is available for definite
64 inference. Any variables introduced by a variable declaration are visible
65 from the point of declaration until the end of the enclosing block scope.
66
67 ## Expression statements
68
69 > **<sup>Syntax</sup>**\
70 > _ExpressionStatement_ :\
71 > &nbsp;&nbsp; &nbsp;&nbsp; [_ExpressionWithoutBlock_][expression] `;`\
72 > &nbsp;&nbsp; | [_ExpressionWithBlock_][expression] `;`<sup>?</sup>
73
74 An *expression statement* is one that evaluates an [expression] and ignores its
75 result. As a rule, an expression statement's purpose is to trigger the effects
76 of evaluating its expression.
77
78 An expression that consists of only a [block expression][block] or control flow
79 expression, if used in a context where a statement is permitted, can omit the
80 trailing semicolon. This can cause an ambiguity between it being parsed as a
81 standalone statement and as a part of another expression; in this case, it is
82 parsed as a statement. The type of [_ExpressionWithBlock_][expression]
83 expressions when used as statements must be the unit type.
84
85 ```rust
86 # let mut v = vec![1, 2, 3];
87 v.pop(); // Ignore the element returned from pop
88 if v.is_empty() {
89 v.push(5);
90 } else {
91 v.remove(0);
92 } // Semicolon can be omitted.
93 [1]; // Separate expression statement, not an indexing expression.
94 ```
95
96 When the trailing semicolon is omitted, the result must be type `()`.
97
98 ```rust
99 // bad: the block's type is i32, not ()
100 // Error: expected `()` because of default return type
101 // if true {
102 // 1
103 // }
104
105 // good: the block's type is i32
106 if true {
107 1
108 } else {
109 2
110 };
111 ```
112
113 ## Attributes on Statements
114
115 Statements accept [outer attributes]. The attributes that have meaning on a
116 statement are [`cfg`], and [the lint check attributes].
117
118 [block]: expressions/block-expr.md
119 [expression]: expressions.md
120 [function]: items/functions.md
121 [item]: items.md
122 [module]: items/modules.md
123 [canonical path]: paths.md#canonical-paths
124 [implementations]: items/implementations.md
125 [variables]: variables.md
126 [outer attributes]: attributes.md
127 [`cfg`]: conditional-compilation.md
128 [the lint check attributes]: attributes/diagnostics.md#lint-check-attributes
129 [pattern]: patterns.md
130 [_ExpressionStatement_]: #expression-statements
131 [_Expression_]: expressions.md
132 [_Item_]: items.md
133 [_LetStatement_]: #let-statements
134 [_MacroInvocationSemi_]: macros.md#macro-invocation
135 [_OuterAttribute_]: attributes.md
136 [_PatternNoTopAlt_]: patterns.md
137 [_Type_]: types.md