@@ -72,7 +72,7 @@ import qualified Data.List.NonEmpty as N
7272%name parseLit lit
7373%name parseAttr export_attribute
7474%name parseTy ty
75- %name parsePat pat
75+ %name parsePat or_pat
7676%name parseStmt stmt
7777%name parseExpr expr
7878%name parseItem mod_item
@@ -805,6 +805,10 @@ lambda_arg :: { Arg Span }
805805-- Patterns --
806806--------------
807807
808+ top_pat :: { Pat Span }
809+ : ' |' or_pat { $> }
810+ | or_pat { $> }
811+
808812-- There is a funky trick going on here around ' IdentP' . When there is a binding mode (ie a ' mut' or
809813-- ' ref' ) or an '@' pattern, everything is fine, but otherwise there is no difference between an
810814-- expression variable path and a pattern. To deal with this, we intercept expression paths with
@@ -831,20 +835,27 @@ pat :: { Pat Span }
831835 | expr_qual_path { PathP (Just (fst (unspan $1 ))) (snd (unspan $1 )) ($1 # $>) }
832836 | lit_or_path ' ...' lit_or_path { RangeP $1 $3 ($1 # $>) }
833837 | lit_or_path ' ..=' lit_or_path { RangeP $1 $3 ($1 # $>) }
834- | expr_path ' {' ' ..' ' }' { StructP $1 [] True ($1 # $>) }
835838 | 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 # $>) }
837840 | expr_mac { MacP $1 (spanOf $1 ) }
838- | ' [' sep_byT(pat ,' ,' ) ' ]' { SliceP $2 ($1 # $>) }
841+ | ' [' sep_byT(or_pat ,' ,' ) ' ]' { SliceP $2 ($1 # $>) }
839842 | ' (' ' )' { 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 ,' ,' ) ' )' {
842845 case toList $2 of
843846 l @ [RestP _] -> TupleP l ($1 # $>) -- (..) is a tuple pattern
844847 [p] -> ParenP p ($1 # $>) -- (<pat>) is parenthesis around a pattern
845848 l -> TupleP l ($1 # $>) -- (<pat1>, <pat2>) is a tuple pattern
846849 }
847850
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+
848859-- Endpoints of range patterns
849860lit_or_path :: { Expr Span }
850861 : expr_path { PathExpr [] Nothing $1 (spanOf $1 ) }
@@ -854,15 +865,16 @@ lit_or_path :: { Expr Span }
854865
855866-- Used in patterns for expression patterns
856867pat_fields :: { ([FieldPat Span], Bool) }
857- : sep_byT(pat_field,' ,' ) { ($1 , False) }
868+ : ' ..' { ([], True) }
869+ | sep_byT(pat_field,' ,' ) { ($1 , False) }
858870 | sep_by1(pat_field,' ,' ) ' ,' ' ..' { (toList $1 , True) }
859871
860872pat_field :: { FieldPat Span }
861873 : binding_mode ident
862874 { FieldPat Nothing (IdentP (unspan $1 ) (unspan $2 ) Nothing (spanOf $2 )) ($1 # $2 ) }
863875 | box binding_mode ident
864876 { 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
866878 { FieldPat (Just (unspan $2 )) $4 ($1 # $2 # $4 ) }
867879
868880
@@ -1090,12 +1102,12 @@ block_like_expr :: { Expr Span }
10901102 : if_expr { $1 }
10911103 | loop inner_attrs_block { let (as,b) = $> in Loop as b Nothing ($1 # b) }
10921104 | 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) }
10951107 | while nostruct_expr inner_attrs_block { let (as,b) = $> in While as $2 b Nothing ($1 # b) }
10961108 | 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) }
10991111 | match nostruct_expr ' {' ' }' { Match [] $2 [] ($1 # $>) }
11001112 | match nostruct_expr ' {' inner_attrs ' }' { Match (toList $4 ) $2 [] ($1 # $>) }
11011113 | match nostruct_expr ' {' arms ' }' { Match [] $2 $4 ($1 # $>) }
@@ -1107,8 +1119,8 @@ block_like_expr :: { Expr Span }
11071119
11081120-- ' if' expressions are a bit special since they can have an arbitrary number of ' else if' chains.
11091121if_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 # $>) }
11121124
11131125else_expr :: { Maybe (Expr Span) }
11141126 : else block { Just (BlockExpr [] $2 (spanOf $2 )) }
@@ -1120,11 +1132,7 @@ else_expr :: { Maybe (Expr Span) }
11201132arms :: { [Arm Span] }
11211133 : ntArm { [$1 ] }
11221134 | 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) }
11281136
11291137arm_guard :: { Maybe (Expr Span) }
11301138 : {- empty -} { Nothing }
@@ -1224,8 +1232,8 @@ union_default_expr :: { Expr Span }
12241232
12251233stmt :: { Stmt Span }
12261234 : 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 # $>) }
12291237 | many(outer_attribute) nonblock_expr ' ;' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
12301238 | many(outer_attribute) block_like_expr ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
12311239 | many(outer_attribute) blockpostfix_expr ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
0 commit comments