@@ -11,22 +11,47 @@ pub(crate) fn pattern(p: &mut Parser) {
11
11
}
12
12
13
13
/// Parses a pattern list separated by pipes `|`
14
- pub ( super ) fn pattern_list ( p : & mut Parser ) {
15
- pattern_list_r ( p, PAT_RECOVERY_SET )
14
+ pub ( super ) fn pattern_top ( p : & mut Parser ) {
15
+ pattern_top_r ( p, PAT_RECOVERY_SET )
16
+ }
17
+
18
+ pub ( crate ) fn pattern_single ( p : & mut Parser ) {
19
+ pattern_single_r ( p, PAT_RECOVERY_SET ) ;
16
20
}
17
21
18
22
/// Parses a pattern list separated by pipes `|`
19
23
/// using the given `recovery_set`
20
- pub ( super ) fn pattern_list_r ( p : & mut Parser , recovery_set : TokenSet ) {
24
+ pub ( super ) fn pattern_top_r ( p : & mut Parser , recovery_set : TokenSet ) {
21
25
p. eat ( T ! [ |] ) ;
22
26
pattern_r ( p, recovery_set) ;
27
+ }
23
28
29
+ /// Parses a pattern list separated by pipes `|`, with no leading `|`,using the
30
+ /// given `recovery_set`
31
+ // test or_pattern
32
+ // fn main() {
33
+ // match () {
34
+ // (_ | _) => (),
35
+ // &(_ | _) => (),
36
+ // (_ | _,) => (),
37
+ // [_ | _,] => (),
38
+ // }
39
+ // }
40
+ fn pattern_r ( p : & mut Parser , recovery_set : TokenSet ) {
41
+ let m = p. start ( ) ;
42
+ pattern_single_r ( p, recovery_set) ;
43
+
44
+ if !p. at ( T ! [ |] ) {
45
+ m. abandon ( p) ;
46
+ return ;
47
+ }
24
48
while p. eat ( T ! [ |] ) {
25
- pattern_r ( p, recovery_set) ;
49
+ pattern_single_r ( p, recovery_set) ;
26
50
}
51
+ m. complete ( p, OR_PAT ) ;
27
52
}
28
53
29
- pub ( super ) fn pattern_r ( p : & mut Parser , recovery_set : TokenSet ) {
54
+ fn pattern_single_r ( p : & mut Parser , recovery_set : TokenSet ) {
30
55
if let Some ( lhs) = atom_pat ( p, recovery_set) {
31
56
// test range_pat
32
57
// fn main() {
@@ -258,19 +283,41 @@ fn ref_pat(p: &mut Parser) -> CompletedMarker {
258
283
let m = p. start ( ) ;
259
284
p. bump ( T ! [ & ] ) ;
260
285
p. eat ( T ! [ mut ] ) ;
261
- pattern ( p) ;
286
+ pattern_single ( p) ;
262
287
m. complete ( p, REF_PAT )
263
288
}
264
289
265
290
// test tuple_pat
266
291
// fn main() {
267
292
// let (a, b, ..) = ();
293
+ // let (a,) = ();
294
+ // let (..) = ();
295
+ // let () = ();
268
296
// }
269
297
fn tuple_pat ( p : & mut Parser ) -> CompletedMarker {
270
298
assert ! ( p. at( T ![ '(' ] ) ) ;
271
299
let m = p. start ( ) ;
272
- tuple_pat_fields ( p) ;
273
- m. complete ( p, TUPLE_PAT )
300
+ p. bump ( T ! [ '(' ] ) ;
301
+ let mut has_comma = false ;
302
+ let mut has_pat = false ;
303
+ let mut has_rest = false ;
304
+ while !p. at ( EOF ) && !p. at ( T ! [ ')' ] ) {
305
+ has_pat = true ;
306
+ if !p. at_ts ( PATTERN_FIRST ) {
307
+ p. error ( "expected a pattern" ) ;
308
+ break ;
309
+ }
310
+ has_rest |= p. at ( T ! [ ..] ) ;
311
+
312
+ pattern ( p) ;
313
+ if !p. at ( T ! [ ')' ] ) {
314
+ has_comma = true ;
315
+ p. expect ( T ! [ , ] ) ;
316
+ }
317
+ }
318
+ p. expect ( T ! [ ')' ] ) ;
319
+
320
+ m. complete ( p, if !has_comma && !has_rest && has_pat { PAREN_PAT } else { TUPLE_PAT } )
274
321
}
275
322
276
323
// test slice_pat
@@ -315,7 +362,7 @@ fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker {
315
362
p. eat ( T ! [ mut ] ) ;
316
363
name ( p) ;
317
364
if with_at && p. eat ( T ! [ @] ) {
318
- pattern ( p) ;
365
+ pattern_single ( p) ;
319
366
}
320
367
m. complete ( p, BIND_PAT )
321
368
}
@@ -330,6 +377,6 @@ fn box_pat(p: &mut Parser) -> CompletedMarker {
330
377
assert ! ( p. at( T ![ box] ) ) ;
331
378
let m = p. start ( ) ;
332
379
p. bump ( T ! [ box] ) ;
333
- pattern ( p) ;
380
+ pattern_single ( p) ;
334
381
m. complete ( p, BOX_PAT )
335
382
}
0 commit comments