@@ -14,7 +14,10 @@ use errors::{Applicability, DiagnosticBuilder};
14
14
15
15
impl < ' a > Parser < ' a > {
16
16
/// Parses a pattern.
17
- pub fn parse_pat ( & mut self , expected : Option < & ' static str > ) -> PResult < ' a , P < Pat > > {
17
+ pub fn parse_pat (
18
+ & mut self ,
19
+ expected : Option < & ' static str >
20
+ ) -> PResult < ' a , P < Pat > > {
18
21
self . parse_pat_with_range_pat ( true , expected)
19
22
}
20
23
@@ -97,6 +100,34 @@ impl<'a> Parser<'a> {
97
100
Ok ( ( ) )
98
101
}
99
102
103
+ /// Parses a pattern, that may be a or-pattern (e.g. `Some(Foo | Bar)`).
104
+ fn parse_pat_with_or ( & mut self , expected : Option < & ' static str > ) -> PResult < ' a , P < Pat > > {
105
+ // Parse the first pattern.
106
+ let first_pat = self . parse_pat ( expected) ?;
107
+
108
+ // If the next token is not a `|`, this is not an or-pattern and
109
+ // we should exit here.
110
+ if !self . check ( & token:: BinOp ( token:: Or ) ) {
111
+ return Ok ( first_pat)
112
+ }
113
+
114
+ let lo = first_pat. span ;
115
+
116
+ let mut pats = vec ! [ first_pat] ;
117
+
118
+ while self . eat ( & token:: BinOp ( token:: Or ) ) {
119
+ pats. push ( self . parse_pat_with_range_pat (
120
+ true , expected
121
+ ) ?) ;
122
+ }
123
+
124
+ let or_pattern_span = lo. to ( self . prev_span ) ;
125
+
126
+ self . sess . or_pattern_spans . borrow_mut ( ) . push ( or_pattern_span) ;
127
+
128
+ Ok ( self . mk_pat ( or_pattern_span, PatKind :: Or ( pats) ) )
129
+ }
130
+
100
131
/// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
101
132
/// allowed).
102
133
fn parse_pat_with_range_pat (
@@ -240,7 +271,9 @@ impl<'a> Parser<'a> {
240
271
241
272
/// Parse a tuple or parenthesis pattern.
242
273
fn parse_pat_tuple_or_parens ( & mut self ) -> PResult < ' a , PatKind > {
243
- let ( fields, trailing_comma) = self . parse_paren_comma_seq ( |p| p. parse_pat ( None ) ) ?;
274
+ let ( fields, trailing_comma) = self . parse_paren_comma_seq ( |p| {
275
+ p. parse_pat_with_or ( None )
276
+ } ) ?;
244
277
245
278
// Here, `(pat,)` is a tuple pattern.
246
279
// For backward compatibility, `(..)` is a tuple pattern as well.
@@ -483,7 +516,7 @@ impl<'a> Parser<'a> {
483
516
err. span_label ( self . token . span , msg) ;
484
517
return Err ( err) ;
485
518
}
486
- let ( fields, _) = self . parse_paren_comma_seq ( |p| p. parse_pat ( None ) ) ?;
519
+ let ( fields, _) = self . parse_paren_comma_seq ( |p| p. parse_pat_with_or ( None ) ) ?;
487
520
Ok ( PatKind :: TupleStruct ( path, fields) )
488
521
}
489
522
@@ -627,7 +660,7 @@ impl<'a> Parser<'a> {
627
660
// Parsing a pattern of the form "fieldname: pat"
628
661
let fieldname = self . parse_field_name ( ) ?;
629
662
self . bump ( ) ;
630
- let pat = self . parse_pat ( None ) ?;
663
+ let pat = self . parse_pat_with_or ( None ) ?;
631
664
hi = pat. span ;
632
665
( pat, fieldname, false )
633
666
} else {
0 commit comments