@@ -72,7 +72,7 @@ import qualified Data.List.NonEmpty as N
72
72
%name parseLit lit
73
73
%name parseAttr export_attribute
74
74
%name parseTy ty
75
- %name parsePat pat
75
+ %name parsePat or_pat
76
76
%name parseStmt stmt
77
77
%name parseExpr expr
78
78
%name parseItem mod_item
@@ -805,6 +805,10 @@ lambda_arg :: { Arg Span }
805
805
-- Patterns --
806
806
--------------
807
807
808
+ top_pat :: { Pat Span }
809
+ : ' |' or_pat { $> }
810
+ | or_pat { $> }
811
+
808
812
-- There is a funky trick going on here around ' IdentP' . When there is a binding mode (ie a ' mut' or
809
813
-- ' ref' ) or an '@' pattern, everything is fine, but otherwise there is no difference between an
810
814
-- expression variable path and a pattern. To deal with this, we intercept expression paths with
@@ -831,20 +835,27 @@ pat :: { Pat Span }
831
835
| expr_qual_path { PathP (Just (fst (unspan $1 ))) (snd (unspan $1 )) ($1 # $>) }
832
836
| lit_or_path ' ...' lit_or_path { RangeP $1 $3 ($1 # $>) }
833
837
| lit_or_path ' ..=' lit_or_path { RangeP $1 $3 ($1 # $>) }
834
- | expr_path ' {' ' ..' ' }' { StructP $1 [] True ($1 # $>) }
835
838
| expr_path ' {' pat_fields ' }' { let (fs,b) = $3 in StructP $1 fs b ($1 # $>) }
836
- | expr_path ' (' sep_byT(pat ,' ,' ) ' )' { TupleStructP $1 $3 ($1 # $>) }
839
+ | expr_path ' (' sep_byT(or_pat ,' ,' ) ' )' { TupleStructP $1 $3 ($1 # $>) }
837
840
| expr_mac { MacP $1 (spanOf $1 ) }
838
- | ' [' sep_byT(pat ,' ,' ) ' ]' { SliceP $2 ($1 # $>) }
841
+ | ' [' sep_byT(or_pat ,' ,' ) ' ]' { SliceP $2 ($1 # $>) }
839
842
| ' (' ' )' { TupleP [] ($1 # $>) }
840
- | ' (' sep_by1(pat ,' ,' ) ' ,' ' )' { TupleP (toList $2 ) ($1 # $>) }
841
- | ' (' sep_by1(pat ,' ,' ) ' )' {
843
+ | ' (' sep_by1(or_pat ,' ,' ) ' ,' ' )' { TupleP (toList $2 ) ($1 # $>) }
844
+ | ' (' sep_by1(or_pat ,' ,' ) ' )' {
842
845
case toList $2 of
843
846
l @ [RestP _] -> TupleP l ($1 # $>) -- (..) is a tuple pattern
844
847
[p] -> ParenP p ($1 # $>) -- (<pat>) is parenthesis around a pattern
845
848
l -> TupleP l ($1 # $>) -- (<pat1>, <pat2>) is a tuple pattern
846
849
}
847
850
851
+ -- Or-pattern
852
+ or_pat :: { Pat Span }
853
+ : sep_by1(pat,' |' ) {
854
+ case toNonEmpty $1 of
855
+ [p] -> p
856
+ ps -> OrP ps (spanOf ps)
857
+ }
858
+
848
859
-- Endpoints of range patterns
849
860
lit_or_path :: { Expr Span }
850
861
: expr_path { PathExpr [] Nothing $1 (spanOf $1 ) }
@@ -854,15 +865,16 @@ lit_or_path :: { Expr Span }
854
865
855
866
-- Used in patterns for expression patterns
856
867
pat_fields :: { ([FieldPat Span], Bool) }
857
- : sep_byT(pat_field,' ,' ) { ($1 , False) }
868
+ : ' ..' { ([], True) }
869
+ | sep_byT(pat_field,' ,' ) { ($1 , False) }
858
870
| sep_by1(pat_field,' ,' ) ' ,' ' ..' { (toList $1 , True) }
859
871
860
872
pat_field :: { FieldPat Span }
861
873
: binding_mode ident
862
874
{ FieldPat Nothing (IdentP (unspan $1 ) (unspan $2 ) Nothing (spanOf $2 )) ($1 # $2 ) }
863
875
| box binding_mode ident
864
876
{ FieldPat Nothing (BoxP (IdentP (unspan $2 ) (unspan $3 ) Nothing ($2 # $3 )) ($1 # $3 )) ($1 # $3 ) }
865
- | binding_mode ident ' :' pat
877
+ | binding_mode ident ' :' or_pat
866
878
{ FieldPat (Just (unspan $2 )) $4 ($1 # $2 # $4 ) }
867
879
868
880
@@ -1090,12 +1102,12 @@ block_like_expr :: { Expr Span }
1090
1102
: if_expr { $1 }
1091
1103
| loop inner_attrs_block { let (as,b) = $> in Loop as b Nothing ($1 # b) }
1092
1104
| label ' :' loop inner_attrs_block { let (as,b) = $> in Loop as b (Just $1 ) ($1 # b) }
1093
- | for pat in nostruct_expr inner_attrs_block { let (as,b) = $> in ForLoop as $2 $4 b Nothing ($1 # b) }
1094
- | label ' :' for pat in nostruct_expr inner_attrs_block { let (as,b) = $> in ForLoop as $4 $6 b (Just $1 ) ($1 # b) }
1105
+ | for top_pat in nostruct_expr inner_attrs_block { let (as,b) = $> in ForLoop as $2 $4 b Nothing ($1 # b) }
1106
+ | label ' :' for top_pat in nostruct_expr inner_attrs_block { let (as,b) = $> in ForLoop as $4 $6 b (Just $1 ) ($1 # b) }
1095
1107
| while nostruct_expr inner_attrs_block { let (as,b) = $> in While as $2 b Nothing ($1 # b) }
1096
1108
| label ' :' while nostruct_expr inner_attrs_block { let (as,b) = $> in While as $4 b (Just $1 ) ($1 # b) }
1097
- | while let pats ' =' nostruct_expr inner_attrs_block { let (as,b) = $> in WhileLet as $3 $5 b Nothing ($1 # b) }
1098
- | label ' :' while let pats ' =' nostruct_expr inner_attrs_block { let (as,b) = $> in WhileLet as $5 $7 b (Just $1 ) ($1 # b) }
1109
+ | while let top_pat ' =' nostruct_expr inner_attrs_block { let (as,b) = $> in WhileLet as $3 $5 b Nothing ($1 # b) }
1110
+ | label ' :' while let top_pat ' =' nostruct_expr inner_attrs_block { let (as,b) = $> in WhileLet as $5 $7 b (Just $1 ) ($1 # b) }
1099
1111
| match nostruct_expr ' {' ' }' { Match [] $2 [] ($1 # $>) }
1100
1112
| match nostruct_expr ' {' inner_attrs ' }' { Match (toList $4 ) $2 [] ($1 # $>) }
1101
1113
| match nostruct_expr ' {' arms ' }' { Match [] $2 $4 ($1 # $>) }
@@ -1107,8 +1119,8 @@ block_like_expr :: { Expr Span }
1107
1119
1108
1120
-- ' if' expressions are a bit special since they can have an arbitrary number of ' else if' chains.
1109
1121
if_expr :: { Expr Span }
1110
- : if nostruct_expr block else_expr { If [] $2 $3 $4 ($1 # $3 # $>) }
1111
- | if let pats ' =' nostruct_expr block else_expr { IfLet [] $3 $5 $6 $7 ($1 # $6 # $>) }
1122
+ : if nostruct_expr block else_expr { If [] $2 $3 $4 ($1 # $3 # $>) }
1123
+ | if let top_pat ' =' nostruct_expr block else_expr { IfLet [] $3 $5 $6 $7 ($1 # $6 # $>) }
1112
1124
1113
1125
else_expr :: { Maybe (Expr Span) }
1114
1126
: else block { Just (BlockExpr [] $2 (spanOf $2 )) }
@@ -1120,11 +1132,7 @@ else_expr :: { Maybe (Expr Span) }
1120
1132
arms :: { [Arm Span] }
1121
1133
: ntArm { [$1 ] }
1122
1134
| ntArm arms { $1 : $2 }
1123
- | many(outer_attribute) pats arm_guard ' =>' expr_arms { let (e,as) = $> in (Arm $1 $2 $3 e ($1 # $2 # e) : as) }
1124
-
1125
- pats :: { NonEmpty (Pat Span) }
1126
- : ' |' sep_by1(pat,' |' ) { toNonEmpty $2 }
1127
- | sep_by1(pat,' |' ) { toNonEmpty $1 }
1135
+ | many(outer_attribute) top_pat arm_guard ' =>' expr_arms { let (e,as) = $> in (Arm $1 $2 $3 e ($1 # $2 # e) : as) }
1128
1136
1129
1137
arm_guard :: { Maybe (Expr Span) }
1130
1138
: {- empty -} { Nothing }
@@ -1224,8 +1232,8 @@ union_default_expr :: { Expr Span }
1224
1232
1225
1233
stmt :: { Stmt Span }
1226
1234
: ntStmt { $1 }
1227
- | many(outer_attribute) let pat ' :' ty initializer ' ;' { Local $3 (Just $5) $6 $1 ($1 # $2 # $>) }
1228
- | many(outer_attribute) let pat initializer ' ;' { Local $3 Nothing $4 $1 ($1 # $2 # $>) }
1235
+ | many(outer_attribute) let top_pat ' :' ty initializer ' ;' { Local $3 (Just $5) $6 $1 ($1 # $2 # $>) }
1236
+ | many(outer_attribute) let top_pat initializer ' ;' { Local $3 Nothing $4 $1 ($1 # $2 # $>) }
1229
1237
| many(outer_attribute) nonblock_expr ' ;' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
1230
1238
| many(outer_attribute) block_like_expr ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
1231
1239
| many(outer_attribute) blockpostfix_expr ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
0 commit comments