9
9
[ `if let` ] : https://github.com/rust-lang/rfcs/pull/160
10
10
[ `while let` ] : https://github.com/rust-lang/rfcs/pull/214
11
11
12
- Enables "or" patterns for [ ` if let ` ] and [ ` while let ` ] expressions. In other
13
- words, examples like the following are now possible:
12
+ Enables "or" patterns for [ ` if let ` ] and [ ` while let ` ] expressions as well as
13
+ ` let ` statements. In other words, examples like the following are now possible:
14
14
15
15
``` rust
16
16
enum E <T > {
@@ -26,6 +26,11 @@ let r = if let C | D = x { 1 } else { 2 };
26
26
while let A (x ) | B (x ) = source () {
27
27
react_to (x );
28
28
}
29
+
30
+ enum ParameterKind <T , L = T > { Ty (T ), Lifetime (L ), }
31
+
32
+ // Only possible when `L = T` such that `kind : ParameterKind<T, T>`.
33
+ let Ty (x ) | Lifetime (x ) = kind ;
29
34
```
30
35
31
36
# Motivation
@@ -107,7 +112,6 @@ which could have been written as:
107
112
108
113
This version is both shorter and clearer.
109
114
110
-
111
115
With ` while let ` , the ergonomics and in particular the readability can be
112
116
significantly improved.
113
117
@@ -132,6 +136,10 @@ loop {
132
136
133
137
Another major motivation of the RFC is consistency with ` match ` .
134
138
139
+ To keep ` let ` statements consistent with ` if let ` , and to enable the scenario
140
+ exemplified by ` ParameterKind ` in the [ motivation] , these or-patterns are
141
+ allowed at the top level of ` let ` statements.
142
+
135
143
# Guide-level explanation
136
144
[ guide-level-explanation ] : #guide-level-explanation
137
145
@@ -145,8 +153,8 @@ words: cover all cases, be exhaustive, this is not the case (currently) with
145
153
` if/while let ` , which may have a refutable pattern.
146
154
This RFC does not change this.
147
155
148
- The RFC only extends the use of or-patterns from ` match ` es to ` if let ` and
149
- ` while let ` expressions.
156
+ The RFC only extends the use of or-patterns at the top level from ` match ` es
157
+ to ` if let ` and ` while let ` expressions as well as ` let ` statements .
150
158
151
159
For examples, see [ motivation] .
152
160
@@ -188,11 +196,28 @@ to:
188
196
while_let_expr : [ lifetime ':' ] ? "while" "let" pat [ '|' pat ] * '=' expr '{' block '}' ;
189
197
```
190
198
199
+ ### ` let ` statements
200
+
201
+ The statement ` stmt ` grammar is replaced with a language equivalent to:
202
+
203
+ ```
204
+ stmt ::= old_stmt_grammar
205
+ | let_stmt_many
206
+ ;
207
+
208
+ let_stmt_many ::= "let" pat_two_plus "=" expr ";"
209
+
210
+ pat_two_plus ::= pat [ '|' pat ] + ;
211
+ ```
212
+
191
213
## Syntax lowering
192
214
193
- The changes proposed in this RFC can be implemented by transforming the
194
- ` if/while let ` constructs with a syntax-lowering pass into ` match ` and
195
- ` loop ` + ` match ` expressions.
215
+ The changes proposed in this RFC with respect to ` if let ` and ` while let `
216
+ can be implemented by transforming the ` if/while let ` constructs with a
217
+ syntax-lowering pass into ` match ` and ` loop ` + ` match ` expressions.
218
+
219
+ Meanwhile, ` let ` statements can be transformed into a continuation with
220
+ ` match ` as described below.
196
221
197
222
### Examples, ` if let `
198
223
@@ -289,10 +314,41 @@ Result:
289
314
}
290
315
```
291
316
317
+ ## Desugaring ` let ` statements with ` | ` in the top-level pattern
318
+
319
+ This is a possible desugaring that a Rust compiler may do.
320
+ While such a compiler may elect to implement this differently,
321
+ these semantics should be kept.
322
+
323
+ Source:
324
+ ``` rust
325
+ {
326
+ // prefix of statements:
327
+ stmt *
328
+ // The let statement which is the cause for desugaring:
329
+ let_stmt_many
330
+ // the continuation / suffix of statements:
331
+ stmt *
332
+ tail_expr ? // Meta-variable for optional tail expression without ; at end
333
+ }
334
+ ```
335
+ Result
336
+ ``` rust
337
+ {
338
+ stmt *
339
+ match expr {
340
+ pat_two_plus => {
341
+ stmt *
342
+ tail_expr ?
343
+ }
344
+ }
345
+ }
346
+ ```
347
+
292
348
# Drawbacks
293
349
[ drawbacks ] : #drawbacks
294
350
295
- It's one more addition to the grammar.
351
+ This adds more additions to the grammar and makes the compiler more complex .
296
352
297
353
# Rationale and alternatives
298
354
[ alternatives ] : #alternatives
@@ -303,6 +359,9 @@ Consistency with `match` is however on its own reason enough to do this.
303
359
It could be claimed that the ` if/while let ` RFCs already mandate this RFC,
304
360
this RFC does answer that question and instead simply mandates it now.
305
361
362
+ Another alternative is to only deal with ` if/while let ` expressions but not
363
+ ` let ` statements.
364
+
306
365
# Unresolved questions
307
366
[ unresolved ] : #unresolved-questions
308
367
0 commit comments