]> git.proxmox.com Git - rustc.git/blob - src/doc/style-guide/src/statements.md
New upstream version 1.73.0+dfsg1
[rustc.git] / src / doc / style-guide / src / statements.md
1 # Statements
2
3 ## Let statements
4
5 Put a space after the `:` and on both sides of the `=` (if they are present).
6 Don't put a space before the semicolon.
7
8 ```rust
9 // A comment.
10 let pattern: Type = expr;
11
12 let pattern;
13 let pattern: Type;
14 let pattern = expr;
15 ```
16
17 If possible, format the declaration on a single line. If not possible, then try
18 splitting after the `=`, if the declaration fits on two lines. Block-indent the
19 expression.
20
21 ```rust
22 let pattern: Type =
23 expr;
24 ```
25
26 If the first line still does not fit on a single line, split after the `:`, and
27 use block indentation. If the type requires multiple lines, even after
28 line-breaking after the `:`, then place the first line on the same line as the
29 `:`, subject to the [combining rules](expressions.html#combinable-expressions).
30
31 ```rust
32 let pattern:
33 Type =
34 expr;
35 ```
36
37 e.g,
38
39 ```rust
40 let Foo {
41 f: abcd,
42 g: qwer,
43 }: Foo<Bar> =
44 Foo { f, g };
45
46 let (abcd,
47 defg):
48 Baz =
49 { ... }
50 ```
51
52 If the expression covers multiple lines, if the first line of the expression
53 fits in the remaining space, it stays on the same line as the `=`, and the rest
54 of the expression is not further indented. If the first line does not fit, then
55 put the expression on subsequent lines, block indented. If the expression is a
56 block and the type or pattern cover multiple lines, put the opening brace on a
57 new line and not indented (this provides separation for the interior of the
58 block from the type); otherwise, the opening brace follows the `=`.
59
60 Examples:
61
62 ```rust
63 let foo = Foo {
64 f: abcd,
65 g: qwer,
66 };
67
68 let foo =
69 ALongName {
70 f: abcd,
71 g: qwer,
72 };
73
74 let foo: Type = {
75 an_expression();
76 ...
77 };
78
79 let foo:
80 ALongType =
81 {
82 an_expression();
83 ...
84 };
85
86 let Foo {
87 f: abcd,
88 g: qwer,
89 }: Foo<Bar> = Foo {
90 f: blimblimblim,
91 g: blamblamblam,
92 };
93
94 let Foo {
95 f: abcd,
96 g: qwer,
97 }: Foo<Bar> = foo(
98 blimblimblim,
99 blamblamblam,
100 );
101 ```
102
103 ### else blocks (let-else statements)
104
105 A let statement can contain an `else` component, making it a let-else statement.
106 In this case, always apply the same formatting rules to the components preceding
107 the `else` block (i.e. the `let pattern: Type = initializer_expr` portion)
108 as described [for other let statements](#let-statements).
109
110 Format the entire let-else statement on a single line if all the following are
111 true:
112
113 * the entire statement is *short*
114 * the `else` block contains only a single-line expression and no statements
115 * the `else` block contains no comments
116 * the let statement components preceding the `else` block can be formatted on a single line
117
118 ```rust
119 let Some(1) = opt else { return };
120 ```
121
122 Otherwise, the let-else statement requires some line breaks.
123
124 If breaking a let-else statement across multiple lines, never break between the
125 `else` and the `{`, and always break before the `}`.
126
127 If the let statement components preceding the `else` can be formatted on a
128 single line, but the let-else does not qualify to be placed entirely on a
129 single line, put the `else {` on the same line as the initializer expression,
130 with a space between them, then break the line after the `{`. Indent the
131 closing `}` to match the `let`, and indent the contained block one step
132 further.
133
134 ```rust
135 let Some(1) = opt else {
136 return;
137 };
138
139 let Some(1) = opt else {
140 // nope
141 return
142 };
143 ```
144
145 If the let statement components preceding the `else` can be formatted on a
146 single line, but the `else {` does not fit on the same line, break the line
147 before the `else`.
148
149 ```rust
150 let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name
151 else {
152 return;
153 };
154 ```
155
156 If the initializer expression is multi-line, put the `else` keyword and opening
157 brace of the block (i.e. `else {`) on the same line as the end of the
158 initializer expression, with a space between them, if and only if all the
159 following are true:
160
161 * The initializer expression ends with one or more closing
162 parentheses, square brackets, and/or braces
163 * There is nothing else on that line
164 * That line has the same indentation level as the initial `let` keyword.
165
166 For example:
167
168 ```rust
169 let Some(x) = y.foo(
170 "abc",
171 fairly_long_identifier,
172 "def",
173 "123456",
174 "string",
175 "cheese",
176 ) else {
177 bar()
178 }
179 ```
180
181 Otherwise, put the `else` keyword and opening brace on the next line after the
182 end of the initializer expression, with the `else` keyword at the same
183 indentation level as the `let` keyword.
184
185 For example:
186
187 ```rust
188 fn main() {
189 let Some(x) = abcdef()
190 .foo(
191 "abc",
192 some_really_really_really_long_ident,
193 "ident",
194 "123456",
195 )
196 .bar()
197 .baz()
198 .qux("fffffffffffffffff")
199 else {
200 return
201 };
202
203 let Some(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) =
204 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
205 else {
206 return;
207 };
208
209 let LongStructName(AnotherStruct {
210 multi,
211 line,
212 pattern,
213 }) = slice.as_ref()
214 else {
215 return;
216 };
217
218 let LongStructName(AnotherStruct {
219 multi,
220 line,
221 pattern,
222 }) = multi_line_function_call(
223 arg1,
224 arg2,
225 arg3,
226 arg4,
227 ) else {
228 return;
229 };
230 }
231 ```
232
233 ## Macros in statement position
234
235 For a macro use in statement position, use parentheses or square brackets as
236 delimiters, and terminate it with a semicolon. Do not put spaces around the
237 name, `!`, the delimiters, or the `;`.
238
239 ```rust
240 // A comment.
241 a_macro!(...);
242 ```
243
244 ## Expressions in statement position
245
246 Do not put space between the expression and the semicolon.
247
248 ```
249 <expr>;
250 ```
251
252 Terminate all expressions in statement position with a semicolon, unless they
253 end with a block or are used as the value for a block.
254
255 E.g.,
256
257 ```rust
258 {
259 an_expression();
260 expr_as_value()
261 }
262
263 return foo();
264
265 loop {
266 break;
267 }
268 ```
269
270 Use a semicolon where an expression has void type, even if it could be
271 propagated. E.g.,
272
273 ```rust
274 fn foo() { ... }
275
276 fn bar() {
277 foo();
278 }
279 ```