@@ -15,6 +15,17 @@ pub use self::UnsafeSource::*;
15
15
pub use self :: PathParameters :: * ;
16
16
pub use symbol:: { Ident , Symbol as Name } ;
17
17
pub 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
+ } ;
18
29
19
30
use syntax_pos:: { Span , DUMMY_SP } ;
20
31
use codemap:: { respan, Spanned } ;
@@ -28,6 +39,7 @@ use tokenstream::{ThinTokenStream, TokenStream};
28
39
29
40
use serialize:: { self , Encoder , Decoder } ;
30
41
use std:: collections:: HashSet ;
42
+ use std:: cmp:: Ordering ;
31
43
use std:: fmt;
32
44
use std:: rc:: Rc ;
33
45
use std:: u32;
@@ -730,6 +742,7 @@ impl BinOpKind {
730
742
_ => false
731
743
}
732
744
}
745
+
733
746
pub fn is_comparison ( & self ) -> bool {
734
747
use self :: BinOpKind :: * ;
735
748
match * self {
@@ -740,6 +753,7 @@ impl BinOpKind {
740
753
false ,
741
754
}
742
755
}
756
+
743
757
/// Returns `true` if the binary operator takes its arguments by value
744
758
pub fn is_by_value ( & self ) -> bool {
745
759
!self . is_comparison ( )
@@ -903,6 +917,129 @@ pub struct Expr {
903
917
pub attrs : ThinVec < Attribute >
904
918
}
905
919
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
+
906
1043
impl Expr {
907
1044
/// Wether this expression would be valid somewhere that expects a value, for example, an `if`
908
1045
/// condition.
@@ -966,6 +1103,49 @@ impl Expr {
966
1103
967
1104
Some ( P ( Ty { node, id : self . id , span : self . span } ) )
968
1105
}
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
+ }
969
1149
}
970
1150
971
1151
impl fmt:: Debug for Expr {
0 commit comments