@@ -28,7 +28,7 @@ To get information about transition states and such, run
28
28
29
29
module Language.Rust .Parser .Internal (
30
30
parseLit, parseAttr, parseTy, parsePat, parseStmt, parseExpr, parseItem, parseSourceFile,
31
- parseBlock, parseImplItem, parseTraitItem, parseTt, parseTyParamBound, parseTyParam,
31
+ parseBlock, parseImplItem, parseTraitItem, parseTt, parseTyParam,
32
32
parseGenerics, parseWhereClause, parseLifetimeDef, parseArg
33
33
) where
34
34
@@ -48,7 +48,7 @@ import Text.Read (readMaybe)
48
48
%name parseLit lit
49
49
%name parseAttr attribute
50
50
%name parseTy ty_general
51
- %name parsePat pat
51
+ %name parsePat export_pat
52
52
%name parseArg export_arg
53
53
%name parseStmt stmt
54
54
%name parseExpr expr
@@ -58,7 +58,6 @@ import Text.Read (readMaybe)
58
58
%name parseImplItem impl_item
59
59
%name parseTraitItem trait_item
60
60
%name parseTt token_tree
61
- %name parseTyParamBound ty_param_bound_mod
62
61
%name parseTyParam ty_param
63
62
%name parseLifetimeDef lifetime_def
64
63
%name parseWhereClause where_clause
@@ -1065,15 +1064,12 @@ comma_arms :: { [Arm Span] }
1065
1064
1066
1065
-- An expression followed by match arms. If there is a comma needed, it is added
1067
1066
expr_arms :: { (Expr Span, [Arm Span]) }
1068
- : gen_expression(nonblock_expr,expr,expr) comma_arms { ($1 , $2 ) }
1069
- | paren_expr comma_arms { ($1 , $2 ) }
1070
- | struct_expr comma_arms { ($1 , $2 ) }
1067
+ : nonblock_expr comma_arms { ($1 , $2 ) }
1068
+ | postfix_block_expr comma_arms { ($1 , $2 ) }
1069
+ | vis_safety_block comma_arms { ($1 , $2 ) }
1070
+ | vis_safety_block arms { ($1 , $2 ) }
1071
1071
| block_like_expr comma_arms { ($1 , $2 ) }
1072
- | inner_attrs_block comma_arms { let (as,b) = $1 in (BlockExpr as b (spanOf b), $2 ) }
1073
- | inner_attrs_block arms { let (as,b) = $1 in (BlockExpr as b (spanOf b), $2 ) }
1074
- | unsafe inner_attrs_block comma_arms
1075
- { let (as, Block ss r x) = $2 in (BlockExpr as (Block ss Unsafe ($1 # x)) ($1 # x), $3 ) }
1076
-
1072
+ | block_like_expr arms { ($1 , $2 ) }
1077
1073
1078
1074
-- As per https:// github.com/rust-lang/rust/issues/15701 (as of March 10 2017), the only way to have
1079
1075
-- attributes on expressions should be with inner attributes on a paren expression.
@@ -1123,24 +1119,104 @@ field :: { Field Span }
1123
1119
----------------
1124
1120
-- Statements --
1125
1121
----------------
1122
+ -- Postfix expressions that can come after an expression block, in a ' stmt'
1123
+ --
1124
+ -- * `{ 1 }[0]` isn' t here because it is treated as `{ 1 }; [0 ]`
1125
+ -- * `{ 1 }(0 )` isn' t here because it is treated as `{ 1 }; (0)`
1126
+ --
1127
+ postfix_block(lhs) :: { Expr Span }
1128
+ -- postfix expressions
1129
+ : lhs ' ?' { Try [] $1 ($1 # $>) }
1130
+ | lhs ' .' ident %prec FIELD { FieldAccess [] $1 (unspan $3) ($1 # $>) }
1131
+ | lhs ' .' ident ' (' sep_byT(expr,' ,' ) ' )'
1132
+ { MethodCall [] $1 (unspan $3) Nothing $5 ($1 # $>) }
1133
+ | lhs ' .' ident ' ::' ' <' sep_byT(ty,' ,' ) ' >' ' (' sep_byT(expr,' ,' ) ' )'
1134
+ { MethodCall [] $1 (unspan $3) (Just $6) $9 ($1 # $>) }
1135
+ | lhs ' .' int {%
1136
+ case lit $3 of
1137
+ Int Dec i Unsuffixed _ -> pure (TupField [] $1 (fromIntegral i) ($1 # $3))
1138
+ _ -> parseError $3
1139
+ }
1140
+
1141
+ gen_expression_block(lhs,rhs,rhs2) :: { Expr Span }
1142
+ : lhs ' ?' { Try [] $1 ($1 # $>) }
1143
+ | lhs ' [' expr ' ]' { Index [] $1 $3 ($1 # $>) }
1144
+ | lhs ' (' sep_byT(expr,' ,' ) ' )' { Call [] $1 $3 ($1 # $>) }
1145
+ | lhs ' .' ident %prec FIELD { FieldAccess [] $1 (unspan $3) ($1 # $>) }
1146
+ | lhs ' .' ident ' (' sep_byT(expr,' ,' ) ' )'
1147
+ { MethodCall [] $1 (unspan $3) Nothing $5 ($1 # $>) }
1148
+ | lhs ' .' ident ' ::' ' <' sep_byT(ty,' ,' ) ' >' ' (' sep_byT(expr,' ,' ) ' )'
1149
+ { MethodCall [] $1 (unspan $3) (Just $6) $9 ($1 # $>) }
1150
+ | lhs ' .' int {%
1151
+ case lit $3 of
1152
+ Int Dec i Unsuffixed _ -> pure (TupField [] $1 (fromIntegral i) ($1 # $3))
1153
+ _ -> parseError $3
1154
+ }
1155
+ -- unary expressions
1156
+ | lhs ' :' ty_no_plus { TypeAscription [] $1 $3 ($1 # $>) }
1157
+ | lhs as ty_no_plus { Cast [] $1 $3 ($1 # $>) }
1158
+ -- binary expressions
1159
+ | lhs ' *' rhs { Binary [] MulOp $1 $3 ($1 # $>) }
1160
+ | lhs ' /' rhs { Binary [] DivOp $1 $3 ($1 # $>) }
1161
+ | lhs ' %' rhs { Binary [] RemOp $1 $3 ($1 # $>) }
1162
+ | lhs ' +' rhs { Binary [] AddOp $1 $3 ($1 # $>) }
1163
+ | lhs ' -' rhs { Binary [] SubOp $1 $3 ($1 # $>) }
1164
+ | lhs ' <<' rhs { Binary [] ShlOp $1 $3 ($1 # $>) }
1165
+ | lhs ' >>' rhs { Binary [] ShrOp $1 $3 ($1 # $>) }
1166
+ | lhs ' &' rhs { Binary [] BitAndOp $1 $3 ($1 # $>) }
1167
+ | lhs ' ^' rhs { Binary [] BitXorOp $1 $3 ($1 # $>) }
1168
+ | lhs ' |' rhs { Binary [] BitOrOp $1 $3 ($1 # $>) }
1169
+ | lhs ' ==' rhs { Binary [] EqOp $1 $3 ($1 # $>) }
1170
+ | lhs ' !=' rhs { Binary [] NeOp $1 $3 ($1 # $>) }
1171
+ | lhs ' <' rhs { Binary [] LtOp $1 $3 ($1 # $>) }
1172
+ | lhs ' >' rhs { Binary [] GtOp $1 $3 ($1 # $>) }
1173
+ | lhs ' <=' rhs { Binary [] LeOp $1 $3 ($1 # $>) }
1174
+ | lhs ' >=' rhs { Binary [] GeOp $1 $3 ($1 # $>) }
1175
+ | lhs ' &&' rhs { Binary [] AndOp $1 $3 ($1 # $>) }
1176
+ | lhs ' ||' rhs { Binary [] OrOp $1 $3 ($1 # $>) }
1177
+ -- range expressions
1178
+ | lhs ' ..' %prec POSTFIXRNG { Range [] (Just $1) Nothing HalfOpen ($1 # $>) }
1179
+ | lhs ' ...' %prec POSTFIXRNG { Range [] (Just $1) Nothing Closed ($1 # $>) }
1180
+ | lhs ' ..' rhs2 %prec INFIXRNG { Range [] (Just $1) (Just $3) HalfOpen ($1 # $>) }
1181
+ | lhs ' ...' rhs2 %prec INFIXRNG { Range [] (Just $1) (Just $3) Closed ($1 # $>) }
1182
+ -- assignment expressions
1183
+ | lhs ' <-' rhs { InPlace [] $1 $3 ($1 # $>) }
1184
+ | lhs ' =' rhs { Assign [] $1 $3 ($1 # $>) }
1185
+ | lhs ' >>=' rhs { AssignOp [] ShrOp $1 $3 ($1 # $>) }
1186
+ | lhs ' <<=' rhs { AssignOp [] ShlOp $1 $3 ($1 # $>) }
1187
+ | lhs ' -=' rhs { AssignOp [] SubOp $1 $3 ($1 # $>) }
1188
+ | lhs ' +=' rhs { AssignOp [] AddOp $1 $3 ($1 # $>) }
1189
+ | lhs ' *=' rhs { AssignOp [] MulOp $1 $3 ($1 # $>) }
1190
+ | lhs ' /=' rhs { AssignOp [] DivOp $1 $3 ($1 # $>) }
1191
+ | lhs ' ^=' rhs { AssignOp [] BitXorOp $1 $3 ($1 # $>) }
1192
+ | lhs ' |=' rhs { AssignOp [] BitOrOp $1 $3 ($1 # $>) }
1193
+ | lhs ' &=' rhs { AssignOp [] BitAndOp $1 $3 ($1 # $>) }
1194
+ | lhs ' %=' rhs { AssignOp [] RemOp $1 $3 ($1 # $>) }
1195
+
1196
+
1197
+ postfix_block_expr :: { Expr Span }
1198
+ : postfix_block(block_like_expr) { $1 }
1199
+ | postfix_block(vis_safety_block) { $1 }
1200
+ | gen_expression_block(postfix_block_expr,expr,expr) { $1 }
1201
+
1202
+ vis_safety_block :: { Expr Span }
1203
+ : pub_or_inherited safety inner_attrs_block {%
1204
+ let (as, Block ss r x) = $3
1205
+ e = BlockExpr as (Block ss (unspan $2) ($2 # x)) ($2 # x)
1206
+ in noVis $1 e
1207
+ }
1208
+
1126
1209
1127
1210
stmt :: { Stmt Span }
1128
1211
: ntStmt { $1 }
1129
1212
| many(outer_attribute) let pat ' :' ty initializer ' ;' { Local $3 (Just $5) $6 $1 ($1 # $2 # $>) }
1130
1213
| many(outer_attribute) let pat initializer ' ;' { Local $3 Nothing $4 $1 ($1 # $2 # $>) }
1131
1214
| many(outer_attribute) nonblock_expr ' ;' { toStmt ($1 `addAttrs` $2) True False ($1 # $2 # $3) }
1132
1215
| many(outer_attribute) block_like_expr ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
1216
+ | many(outer_attribute) postfix_block_expr ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $3) }
1133
1217
| many(outer_attribute) block_like_expr %prec NOSEMI { toStmt ($1 `addAttrs` $2) False True ($1 # $2) }
1134
- | many(outer_attribute) pub_or_inherited safety inner_attrs_block ' ;' {%
1135
- let (as, Block ss r x) = $4
1136
- e = BlockExpr ($1 ++ as) (Block ss (unspan $3) ($3 # x)) ($3 # x)
1137
- in noVis $2 (toStmt e True True ($1 # e # $>))
1138
- }
1139
- | many(outer_attribute) pub_or_inherited safety inner_attrs_block %prec NOSEMI {%
1140
- let (as, Block ss r x) = $4
1141
- e = BlockExpr ($1 ++ as) (Block ss (unspan $3) ($3 # x)) ($3 # x)
1142
- in noVis $2 (toStmt e False True ($1 # e))
1143
- }
1218
+ | many(outer_attribute) vis_safety_block ' ;' { toStmt ($1 `addAttrs` $2) True True ($1 # $2 # $>) }
1219
+ | many(outer_attribute) vis_safety_block %prec NOSEMI { toStmt ($1 `addAttrs` $2) False True ($1 # $2) }
1144
1220
| gen_item(pub_or_inherited) { ItemStmt $1 (spanOf $1) }
1145
1221
| many(outer_attribute) expr_path ' !' ident ' [' many(token_tree) ' ]' ' ;'
1146
1222
{ ItemStmt (macroItem $1 (Just (unspan $4)) (Mac $2 $6 ($2 # $>)) ($1 # $2 # $>)) ($1 # $2 # $>) }
@@ -1162,6 +1238,7 @@ stmts_possibly_no_semi :: { [Maybe (Stmt Span)] }
1162
1238
: stmtOrSemi stmts_possibly_no_semi { $1 : $2 }
1163
1239
| stmtOrSemi { [$1] }
1164
1240
| many(outer_attribute) nonblock_expr { [Just (toStmt ($1 `addAttrs` $2) False False ($1 # $2))] }
1241
+ | many(outer_attribute) postfix_block_expr { [Just (toStmt ($1 `addAttrs` $2) False True ($1 # $2))] }
1165
1242
1166
1243
initializer :: { Maybe (Expr Span) }
1167
1244
: ' =' expr { Just $2 }
@@ -1570,6 +1647,10 @@ export_arg :: { Arg Span }
1570
1647
: arg_general { $1 }
1571
1648
| arg_self { $1 }
1572
1649
1650
+ -- Exporting ' pat' directly screws up expressions like ' x && y()'
1651
+ export_pat :: { Pat Span }
1652
+ : pat { $1 }
1653
+
1573
1654
{
1574
1655
-- | Parser for literals.
1575
1656
parseLit :: P (Lit Span)
@@ -1610,9 +1691,6 @@ parseTt :: P TokenTree
1610
1691
-- | Parser for lifetime definitions
1611
1692
parseLifetimeDef :: P (LifetimeDef Span)
1612
1693
1613
- -- | Parser for type parameter bound
1614
- parseTyParamBound :: P (TyParamBound Span)
1615
-
1616
1694
-- | Parser for a type parameter
1617
1695
parseTyParam :: P (TyParam Span)
1618
1696
0 commit comments