@@ -39,7 +39,9 @@ pub use crate::format::*;
3939use crate :: ptr:: P ;
4040use crate :: token:: { self , CommentKind , Delimiter } ;
4141use crate :: tokenstream:: { DelimSpan , LazyAttrTokenStream , TokenStream } ;
42- pub use crate :: util:: parser:: ExprPrecedence ;
42+ use crate :: util:: parser:: {
43+ AssocOp , PREC_CLOSURE , PREC_JUMP , PREC_PREFIX , PREC_RANGE , PREC_UNAMBIGUOUS ,
44+ } ;
4345
4446/// A "Label" is an identifier of some point in sources,
4547/// e.g. in the following code:
@@ -1319,53 +1321,71 @@ impl Expr {
13191321 Some ( P ( Ty { kind, id : self . id , span : self . span , tokens : None } ) )
13201322 }
13211323
1322- pub fn precedence ( & self ) -> ExprPrecedence {
1324+ pub fn precedence ( & self ) -> i8 {
13231325 match self . kind {
1324- ExprKind :: Array ( _) => ExprPrecedence :: Array ,
1325- ExprKind :: ConstBlock ( _) => ExprPrecedence :: ConstBlock ,
1326- ExprKind :: Call ( ..) => ExprPrecedence :: Call ,
1327- ExprKind :: MethodCall ( ..) => ExprPrecedence :: MethodCall ,
1328- ExprKind :: Tup ( _) => ExprPrecedence :: Tup ,
1329- ExprKind :: Binary ( op, ..) => ExprPrecedence :: Binary ( op. node ) ,
1330- ExprKind :: Unary ( ..) => ExprPrecedence :: Unary ,
1331- ExprKind :: Lit ( _) | ExprKind :: IncludedBytes ( ..) => ExprPrecedence :: Lit ,
1332- ExprKind :: Cast ( ..) => ExprPrecedence :: Cast ,
1333- ExprKind :: Let ( ..) => ExprPrecedence :: Let ,
1334- ExprKind :: If ( ..) => ExprPrecedence :: If ,
1335- ExprKind :: While ( ..) => ExprPrecedence :: While ,
1336- ExprKind :: ForLoop { .. } => ExprPrecedence :: ForLoop ,
1337- ExprKind :: Loop ( ..) => ExprPrecedence :: Loop ,
1338- ExprKind :: Match ( _, _, MatchKind :: Prefix ) => ExprPrecedence :: Match ,
1339- ExprKind :: Match ( _, _, MatchKind :: Postfix ) => ExprPrecedence :: PostfixMatch ,
1340- ExprKind :: Closure ( ..) => ExprPrecedence :: Closure ,
1341- ExprKind :: Block ( ..) => ExprPrecedence :: Block ,
1342- ExprKind :: TryBlock ( ..) => ExprPrecedence :: TryBlock ,
1343- ExprKind :: Gen ( ..) => ExprPrecedence :: Gen ,
1344- ExprKind :: Await ( ..) => ExprPrecedence :: Await ,
1345- ExprKind :: Assign ( ..) => ExprPrecedence :: Assign ,
1346- ExprKind :: AssignOp ( ..) => ExprPrecedence :: AssignOp ,
1347- ExprKind :: Field ( ..) => ExprPrecedence :: Field ,
1348- ExprKind :: Index ( ..) => ExprPrecedence :: Index ,
1349- ExprKind :: Range ( ..) => ExprPrecedence :: Range ,
1350- ExprKind :: Underscore => ExprPrecedence :: Path ,
1351- ExprKind :: Path ( ..) => ExprPrecedence :: Path ,
1352- ExprKind :: AddrOf ( ..) => ExprPrecedence :: AddrOf ,
1353- ExprKind :: Break ( ..) => ExprPrecedence :: Break ,
1354- ExprKind :: Continue ( ..) => ExprPrecedence :: Continue ,
1355- ExprKind :: Ret ( ..) => ExprPrecedence :: Ret ,
1356- ExprKind :: Struct ( ..) => ExprPrecedence :: Struct ,
1357- ExprKind :: Repeat ( ..) => ExprPrecedence :: Repeat ,
1358- ExprKind :: Paren ( ..) => ExprPrecedence :: Paren ,
1359- ExprKind :: Try ( ..) => ExprPrecedence :: Try ,
1360- ExprKind :: Yield ( ..) => ExprPrecedence :: Yield ,
1361- ExprKind :: Yeet ( ..) => ExprPrecedence :: Yeet ,
1362- ExprKind :: Become ( ..) => ExprPrecedence :: Become ,
1363- ExprKind :: InlineAsm ( ..)
1364- | ExprKind :: Type ( ..)
1365- | ExprKind :: OffsetOf ( ..)
1326+ ExprKind :: Closure ( ..) => PREC_CLOSURE ,
1327+
1328+ ExprKind :: Break ( ..)
1329+ | ExprKind :: Continue ( ..)
1330+ | ExprKind :: Ret ( ..)
1331+ | ExprKind :: Yield ( ..)
1332+ | ExprKind :: Yeet ( ..)
1333+ | ExprKind :: Become ( ..) => PREC_JUMP ,
1334+
1335+ // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
1336+ // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
1337+ // ensures that `pprust` will add parentheses in the right places to get the desired
1338+ // parse.
1339+ ExprKind :: Range ( ..) => PREC_RANGE ,
1340+
1341+ // Binop-like expr kinds, handled by `AssocOp`.
1342+ ExprKind :: Binary ( op, ..) => AssocOp :: from_ast_binop ( op. node ) . precedence ( ) as i8 ,
1343+ ExprKind :: Cast ( ..) => AssocOp :: As . precedence ( ) as i8 ,
1344+
1345+ ExprKind :: Assign ( ..) |
1346+ ExprKind :: AssignOp ( ..) => AssocOp :: Assign . precedence ( ) as i8 ,
1347+
1348+ // Unary, prefix
1349+ ExprKind :: AddrOf ( ..)
1350+ // Here `let pats = expr` has `let pats =` as a "unary" prefix of `expr`.
1351+ // However, this is not exactly right. When `let _ = a` is the LHS of a binop we
1352+ // need parens sometimes. E.g. we can print `(let _ = a) && b` as `let _ = a && b`
1353+ // but we need to print `(let _ = a) < b` as-is with parens.
1354+ | ExprKind :: Let ( ..)
1355+ | ExprKind :: Unary ( ..) => PREC_PREFIX ,
1356+
1357+ // Never need parens
1358+ ExprKind :: Array ( _)
1359+ | ExprKind :: Await ( ..)
1360+ | ExprKind :: Block ( ..)
1361+ | ExprKind :: Call ( ..)
1362+ | ExprKind :: ConstBlock ( _)
1363+ | ExprKind :: Field ( ..)
1364+ | ExprKind :: ForLoop { .. }
13661365 | ExprKind :: FormatArgs ( ..)
1367- | ExprKind :: MacCall ( ..) => ExprPrecedence :: Mac ,
1368- ExprKind :: Err ( _) | ExprKind :: Dummy => ExprPrecedence :: Err ,
1366+ | ExprKind :: Gen ( ..)
1367+ | ExprKind :: If ( ..)
1368+ | ExprKind :: IncludedBytes ( ..)
1369+ | ExprKind :: Index ( ..)
1370+ | ExprKind :: InlineAsm ( ..)
1371+ | ExprKind :: Lit ( _)
1372+ | ExprKind :: Loop ( ..)
1373+ | ExprKind :: MacCall ( ..)
1374+ | ExprKind :: Match ( ..)
1375+ | ExprKind :: MethodCall ( ..)
1376+ | ExprKind :: OffsetOf ( ..)
1377+ | ExprKind :: Paren ( ..)
1378+ | ExprKind :: Path ( ..)
1379+ | ExprKind :: Repeat ( ..)
1380+ | ExprKind :: Struct ( ..)
1381+ | ExprKind :: Try ( ..)
1382+ | ExprKind :: TryBlock ( ..)
1383+ | ExprKind :: Tup ( _)
1384+ | ExprKind :: Type ( ..)
1385+ | ExprKind :: Underscore
1386+ | ExprKind :: While ( ..)
1387+ | ExprKind :: Err ( _)
1388+ | ExprKind :: Dummy => PREC_UNAMBIGUOUS ,
13691389 }
13701390 }
13711391
0 commit comments