@@ -15,6 +15,17 @@ pub use self::UnsafeSource::*;
1515pub use self :: PathParameters :: * ;
1616pub use symbol:: { Ident , Symbol as Name } ;
1717pub use util:: ThinVec ;
18+ pub use util:: parser:: {
19+ AssocOp ,
20+ PREC_RESET ,
21+ PREC_CLOSURE ,
22+ PREC_JUMP ,
23+ PREC_RANGE ,
24+ PREC_PREFIX ,
25+ PREC_POSTFIX ,
26+ PREC_PAREN ,
27+ PREC_FORCE_PAREN ,
28+ } ;
1829
1930use syntax_pos:: { Span , DUMMY_SP } ;
2031use codemap:: { respan, Spanned } ;
@@ -28,6 +39,7 @@ use tokenstream::{ThinTokenStream, TokenStream};
2839
2940use serialize:: { self , Encoder , Decoder } ;
3041use std:: collections:: HashSet ;
42+ use std:: cmp:: Ordering ;
3143use std:: fmt;
3244use std:: rc:: Rc ;
3345use std:: u32;
@@ -730,6 +742,7 @@ impl BinOpKind {
730742 _ => false
731743 }
732744 }
745+
733746 pub fn is_comparison ( & self ) -> bool {
734747 use self :: BinOpKind :: * ;
735748 match * self {
@@ -740,6 +753,7 @@ impl BinOpKind {
740753 false ,
741754 }
742755 }
756+
743757 /// Returns `true` if the binary operator takes its arguments by value
744758 pub fn is_by_value ( & self ) -> bool {
745759 !self . is_comparison ( )
@@ -903,6 +917,129 @@ pub struct Expr {
903917 pub attrs : ThinVec < Attribute >
904918}
905919
920+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
921+ pub enum ExprPrecedence {
922+ Closure ,
923+ Break ,
924+ Continue ,
925+ Ret ,
926+ Yield ,
927+
928+ Range ,
929+
930+ Binary ( BinOpKind ) ,
931+
932+ InPlace ,
933+ Cast ,
934+ Type ,
935+
936+ Assign ,
937+ AssignOp ,
938+
939+ Box ,
940+ AddrOf ,
941+ Unary ,
942+
943+ Call ,
944+ MethodCall ,
945+ Field ,
946+ TupField ,
947+ Index ,
948+ Try ,
949+ InlineAsm ,
950+ Mac ,
951+
952+ Array ,
953+ Repeat ,
954+ Tup ,
955+ Lit ,
956+ Path ,
957+ Paren ,
958+ If ,
959+ IfLet ,
960+ While ,
961+ WhileLet ,
962+ ForLoop ,
963+ Loop ,
964+ Match ,
965+ Block ,
966+ Catch ,
967+ Struct ,
968+ }
969+
970+ impl PartialOrd for ExprPrecedence {
971+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
972+ Some ( self . order ( ) . cmp ( & other. order ( ) ) )
973+ }
974+ }
975+
976+ impl Ord for ExprPrecedence {
977+ fn cmp ( & self , other : & Self ) -> Ordering {
978+ self . order ( ) . cmp ( & other. order ( ) )
979+ }
980+ }
981+
982+ impl ExprPrecedence {
983+ pub fn order ( self ) -> i8 {
984+ match self {
985+ ExprPrecedence :: Closure => PREC_CLOSURE ,
986+
987+ ExprPrecedence :: Break |
988+ ExprPrecedence :: Continue |
989+ ExprPrecedence :: Ret |
990+ ExprPrecedence :: Yield => PREC_JUMP ,
991+
992+ // `Range` claims to have higher precedence than `Assign`, but `x .. x = x` fails to
993+ // parse, instead of parsing as `(x .. x) = x`. Giving `Range` a lower precedence
994+ // ensures that `pprust` will add parentheses in the right places to get the desired
995+ // parse.
996+ ExprPrecedence :: Range => PREC_RANGE ,
997+
998+ // Binop-like expr kinds, handled by `AssocOp`.
999+ ExprPrecedence :: Binary ( op) => AssocOp :: from_ast_binop ( op) . precedence ( ) as i8 ,
1000+ ExprPrecedence :: InPlace => AssocOp :: Inplace . precedence ( ) as i8 ,
1001+ ExprPrecedence :: Cast => AssocOp :: As . precedence ( ) as i8 ,
1002+ ExprPrecedence :: Type => AssocOp :: Colon . precedence ( ) as i8 ,
1003+
1004+ ExprPrecedence :: Assign |
1005+ ExprPrecedence :: AssignOp => AssocOp :: Assign . precedence ( ) as i8 ,
1006+
1007+ // Unary, prefix
1008+ ExprPrecedence :: Box |
1009+ ExprPrecedence :: AddrOf |
1010+ ExprPrecedence :: Unary => PREC_PREFIX ,
1011+
1012+ // Unary, postfix
1013+ ExprPrecedence :: Call |
1014+ ExprPrecedence :: MethodCall |
1015+ ExprPrecedence :: Field |
1016+ ExprPrecedence :: TupField |
1017+ ExprPrecedence :: Index |
1018+ ExprPrecedence :: Try |
1019+ ExprPrecedence :: InlineAsm |
1020+ ExprPrecedence :: Mac => PREC_POSTFIX ,
1021+
1022+ // Never need parens
1023+ ExprPrecedence :: Array |
1024+ ExprPrecedence :: Repeat |
1025+ ExprPrecedence :: Tup |
1026+ ExprPrecedence :: Lit |
1027+ ExprPrecedence :: Path |
1028+ ExprPrecedence :: Paren |
1029+ ExprPrecedence :: If |
1030+ ExprPrecedence :: IfLet |
1031+ ExprPrecedence :: While |
1032+ ExprPrecedence :: WhileLet |
1033+ ExprPrecedence :: ForLoop |
1034+ ExprPrecedence :: Loop |
1035+ ExprPrecedence :: Match |
1036+ ExprPrecedence :: Block |
1037+ ExprPrecedence :: Catch |
1038+ ExprPrecedence :: Struct => PREC_PAREN ,
1039+ }
1040+ }
1041+ }
1042+
9061043impl Expr {
9071044 /// Wether this expression would be valid somewhere that expects a value, for example, an `if`
9081045 /// condition.
@@ -966,6 +1103,49 @@ impl Expr {
9661103
9671104 Some ( P ( Ty { node, id : self . id , span : self . span } ) )
9681105 }
1106+
1107+ pub fn precedence ( & self ) -> ExprPrecedence {
1108+ match self . node {
1109+ ExprKind :: Box ( _) => ExprPrecedence :: Box ,
1110+ ExprKind :: InPlace ( ..) => ExprPrecedence :: InPlace ,
1111+ ExprKind :: Array ( _) => ExprPrecedence :: Array ,
1112+ ExprKind :: Call ( ..) => ExprPrecedence :: Call ,
1113+ ExprKind :: MethodCall ( ..) => ExprPrecedence :: MethodCall ,
1114+ ExprKind :: Tup ( _) => ExprPrecedence :: Tup ,
1115+ ExprKind :: Binary ( op, ..) => ExprPrecedence :: Binary ( op. node ) ,
1116+ ExprKind :: Unary ( ..) => ExprPrecedence :: Unary ,
1117+ ExprKind :: Lit ( _) => ExprPrecedence :: Lit ,
1118+ ExprKind :: Type ( ..) | ExprKind :: Cast ( ..) => ExprPrecedence :: Cast ,
1119+ ExprKind :: If ( ..) => ExprPrecedence :: If ,
1120+ ExprKind :: IfLet ( ..) => ExprPrecedence :: IfLet ,
1121+ ExprKind :: While ( ..) => ExprPrecedence :: While ,
1122+ ExprKind :: WhileLet ( ..) => ExprPrecedence :: WhileLet ,
1123+ ExprKind :: ForLoop ( ..) => ExprPrecedence :: ForLoop ,
1124+ ExprKind :: Loop ( ..) => ExprPrecedence :: Loop ,
1125+ ExprKind :: Match ( ..) => ExprPrecedence :: Match ,
1126+ ExprKind :: Closure ( ..) => ExprPrecedence :: Closure ,
1127+ ExprKind :: Block ( ..) => ExprPrecedence :: Block ,
1128+ ExprKind :: Catch ( ..) => ExprPrecedence :: Catch ,
1129+ ExprKind :: Assign ( ..) => ExprPrecedence :: Assign ,
1130+ ExprKind :: AssignOp ( ..) => ExprPrecedence :: AssignOp ,
1131+ ExprKind :: Field ( ..) => ExprPrecedence :: Field ,
1132+ ExprKind :: TupField ( ..) => ExprPrecedence :: TupField ,
1133+ ExprKind :: Index ( ..) => ExprPrecedence :: Index ,
1134+ ExprKind :: Range ( ..) => ExprPrecedence :: Range ,
1135+ ExprKind :: Path ( ..) => ExprPrecedence :: Path ,
1136+ ExprKind :: AddrOf ( ..) => ExprPrecedence :: AddrOf ,
1137+ ExprKind :: Break ( ..) => ExprPrecedence :: Break ,
1138+ ExprKind :: Continue ( ..) => ExprPrecedence :: Continue ,
1139+ ExprKind :: Ret ( ..) => ExprPrecedence :: Ret ,
1140+ ExprKind :: InlineAsm ( ..) => ExprPrecedence :: InlineAsm ,
1141+ ExprKind :: Mac ( ..) => ExprPrecedence :: Mac ,
1142+ ExprKind :: Struct ( ..) => ExprPrecedence :: Struct ,
1143+ ExprKind :: Repeat ( ..) => ExprPrecedence :: Repeat ,
1144+ ExprKind :: Paren ( ..) => ExprPrecedence :: Paren ,
1145+ ExprKind :: Try ( ..) => ExprPrecedence :: Try ,
1146+ ExprKind :: Yield ( ..) => ExprPrecedence :: Yield ,
1147+ }
1148+ }
9691149}
9701150
9711151impl fmt:: Debug for Expr {
0 commit comments