@@ -3,51 +3,15 @@ use rustc_span::kw;
3
3
use crate::ast::{self, BinOpKind};
4
4
use crate::token::{self, BinOpToken, Token};
5
5
6
- /// Associative operator with precedence.
7
- ///
8
- /// This is the enum which specifies operator precedence and fixity to the parser.
6
+ /// Associative operator.
9
7
#[derive(Copy, Clone, PartialEq, Debug)]
10
8
pub enum AssocOp {
11
- /// `+`
12
- Add,
13
- /// `-`
14
- Subtract,
15
- /// `*`
16
- Multiply,
17
- /// `/`
18
- Divide,
19
- /// `%`
20
- Modulus,
21
- /// `&&`
22
- LAnd,
23
- /// `||`
24
- LOr,
25
- /// `^`
26
- BitXor,
27
- /// `&`
28
- BitAnd,
29
- /// `|`
30
- BitOr,
31
- /// `<<`
32
- ShiftLeft,
33
- /// `>>`
34
- ShiftRight,
35
- /// `==`
36
- Equal,
37
- /// `<`
38
- Less,
39
- /// `<=`
40
- LessEqual,
41
- /// `!=`
42
- NotEqual,
43
- /// `>`
44
- Greater,
45
- /// `>=`
46
- GreaterEqual,
47
- /// `=`
48
- Assign,
9
+ /// A binary op.
10
+ Binary(BinOpKind),
49
11
/// `?=` where ? is one of the assignable BinOps
50
12
AssignOp(BinOpKind),
13
+ /// `=`
14
+ Assign,
51
15
/// `as`
52
16
As,
53
17
/// `..` range
@@ -67,11 +31,21 @@ pub enum Fixity {
67
31
}
68
32
69
33
impl AssocOp {
70
- /// Creates a new AssocOP from a token
34
+ /// Creates a new AssocOp from a token.
71
35
pub fn from_token(t: &Token) -> Option<AssocOp> {
72
36
use AssocOp::*;
73
37
match t.kind {
74
38
token::Eq => Some(Assign),
39
+ token::BinOp(BinOpToken::Plus) => Some(Binary(BinOpKind::Add)),
40
+ token::BinOp(BinOpToken::Minus) => Some(Binary(BinOpKind::Sub)),
41
+ token::BinOp(BinOpToken::Star) => Some(Binary(BinOpKind::Mul)),
42
+ token::BinOp(BinOpToken::Slash) => Some(Binary(BinOpKind::Div)),
43
+ token::BinOp(BinOpToken::Percent) => Some(Binary(BinOpKind::Rem)),
44
+ token::BinOp(BinOpToken::Caret) => Some(Binary(BinOpKind::BitXor)),
45
+ token::BinOp(BinOpToken::And) => Some(Binary(BinOpKind::BitAnd)),
46
+ token::BinOp(BinOpToken::Or) => Some(Binary(BinOpKind::BitOr)),
47
+ token::BinOp(BinOpToken::Shl) => Some(Binary(BinOpKind::Shl)),
48
+ token::BinOp(BinOpToken::Shr) => Some(Binary(BinOpKind::Shr)),
75
49
token::BinOpEq(BinOpToken::Plus) => Some(AssignOp(BinOpKind::Add)),
76
50
token::BinOpEq(BinOpToken::Minus) => Some(AssignOp(BinOpKind::Sub)),
77
51
token::BinOpEq(BinOpToken::Star) => Some(AssignOp(BinOpKind::Mul)),
@@ -82,74 +56,31 @@ impl AssocOp {
82
56
token::BinOpEq(BinOpToken::Or) => Some(AssignOp(BinOpKind::BitOr)),
83
57
token::BinOpEq(BinOpToken::Shl) => Some(AssignOp(BinOpKind::Shl)),
84
58
token::BinOpEq(BinOpToken::Shr) => Some(AssignOp(BinOpKind::Shr)),
85
- token::BinOp(BinOpToken::Plus) => Some(Add),
86
- token::BinOp(BinOpToken::Minus) => Some(Subtract),
87
- token::BinOp(BinOpToken::Star) => Some(Multiply),
88
- token::BinOp(BinOpToken::Slash) => Some(Divide),
89
- token::BinOp(BinOpToken::Percent) => Some(Modulus),
90
- token::BinOp(BinOpToken::Caret) => Some(BitXor),
91
- token::BinOp(BinOpToken::And) => Some(BitAnd),
92
- token::BinOp(BinOpToken::Or) => Some(BitOr),
93
- token::BinOp(BinOpToken::Shl) => Some(ShiftLeft),
94
- token::BinOp(BinOpToken::Shr) => Some(ShiftRight),
95
- token::Lt => Some(Less),
96
- token::Le => Some(LessEqual),
97
- token::Ge => Some(GreaterEqual),
98
- token::Gt => Some(Greater),
99
- token::EqEq => Some(Equal),
100
- token::Ne => Some(NotEqual),
101
- token::AndAnd => Some(LAnd),
102
- token::OrOr => Some(LOr),
59
+ token::Lt => Some(Binary(BinOpKind::Lt)),
60
+ token::Le => Some(Binary(BinOpKind::Le)),
61
+ token::Ge => Some(Binary(BinOpKind::Ge)),
62
+ token::Gt => Some(Binary(BinOpKind::Gt)),
63
+ token::EqEq => Some(Binary(BinOpKind::Eq)),
64
+ token::Ne => Some(Binary(BinOpKind::Ne)),
65
+ token::AndAnd => Some(Binary(BinOpKind::And)),
66
+ token::OrOr => Some(Binary(BinOpKind::Or)),
103
67
token::DotDot => Some(DotDot),
104
68
token::DotDotEq => Some(DotDotEq),
105
69
// DotDotDot is no longer supported, but we need some way to display the error
106
70
token::DotDotDot => Some(DotDotEq),
107
71
// `<-` should probably be `< -`
108
- token::LArrow => Some(Less ),
72
+ token::LArrow => Some(Binary(BinOpKind::Lt) ),
109
73
_ if t.is_keyword(kw::As) => Some(As),
110
74
_ => None,
111
75
}
112
76
}
113
77
114
- /// Creates a new AssocOp from ast::BinOpKind.
115
- pub fn from_ast_binop(op: BinOpKind) -> Self {
116
- use AssocOp::*;
117
- match op {
118
- BinOpKind::Lt => Less,
119
- BinOpKind::Gt => Greater,
120
- BinOpKind::Le => LessEqual,
121
- BinOpKind::Ge => GreaterEqual,
122
- BinOpKind::Eq => Equal,
123
- BinOpKind::Ne => NotEqual,
124
- BinOpKind::Mul => Multiply,
125
- BinOpKind::Div => Divide,
126
- BinOpKind::Rem => Modulus,
127
- BinOpKind::Add => Add,
128
- BinOpKind::Sub => Subtract,
129
- BinOpKind::Shl => ShiftLeft,
130
- BinOpKind::Shr => ShiftRight,
131
- BinOpKind::BitAnd => BitAnd,
132
- BinOpKind::BitXor => BitXor,
133
- BinOpKind::BitOr => BitOr,
134
- BinOpKind::And => LAnd,
135
- BinOpKind::Or => LOr,
136
- }
137
- }
138
-
139
78
/// Gets the precedence of this operator
140
79
pub fn precedence(&self) -> ExprPrecedence {
141
80
use AssocOp::*;
142
81
match *self {
143
82
As => ExprPrecedence::Cast,
144
- Multiply | Divide | Modulus => ExprPrecedence::Product,
145
- Add | Subtract => ExprPrecedence::Sum,
146
- ShiftLeft | ShiftRight => ExprPrecedence::Shift,
147
- BitAnd => ExprPrecedence::BitAnd,
148
- BitXor => ExprPrecedence::BitXor,
149
- BitOr => ExprPrecedence::BitOr,
150
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => ExprPrecedence::Compare,
151
- LAnd => ExprPrecedence::LAnd,
152
- LOr => ExprPrecedence::LOr,
83
+ Binary(bin_op) => bin_op.precedence(),
153
84
DotDot | DotDotEq => ExprPrecedence::Range,
154
85
Assign | AssignOp(_) => ExprPrecedence::Assign,
155
86
}
@@ -161,57 +92,25 @@ impl AssocOp {
161
92
// NOTE: it is a bug to have an operators that has same precedence but different fixities!
162
93
match *self {
163
94
Assign | AssignOp(_) => Fixity::Right,
164
- As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd
165
- | BitXor | BitOr | LAnd | LOr => Fixity::Left,
166
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | DotDot | DotDotEq => {
167
- Fixity::None
168
- }
95
+ Binary(binop) => binop.fixity(),
96
+ As => Fixity::Left,
97
+ DotDot | DotDotEq => Fixity::None,
169
98
}
170
99
}
171
100
172
101
pub fn is_comparison(&self) -> bool {
173
102
use AssocOp::*;
174
103
match *self {
175
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
176
- Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract
177
- | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | DotDotEq => {
178
- false
179
- }
104
+ Binary(binop) => binop.is_comparison(),
105
+ Assign | AssignOp(_) | As | DotDot | DotDotEq => false,
180
106
}
181
107
}
182
108
183
109
pub fn is_assign_like(&self) -> bool {
184
110
use AssocOp::*;
185
111
match *self {
186
112
Assign | AssignOp(_) => true,
187
- Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply
188
- | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor
189
- | BitOr | LAnd | LOr | DotDot | DotDotEq => false,
190
- }
191
- }
192
-
193
- pub fn to_ast_binop(&self) -> Option<BinOpKind> {
194
- use AssocOp::*;
195
- match *self {
196
- Less => Some(BinOpKind::Lt),
197
- Greater => Some(BinOpKind::Gt),
198
- LessEqual => Some(BinOpKind::Le),
199
- GreaterEqual => Some(BinOpKind::Ge),
200
- Equal => Some(BinOpKind::Eq),
201
- NotEqual => Some(BinOpKind::Ne),
202
- Multiply => Some(BinOpKind::Mul),
203
- Divide => Some(BinOpKind::Div),
204
- Modulus => Some(BinOpKind::Rem),
205
- Add => Some(BinOpKind::Add),
206
- Subtract => Some(BinOpKind::Sub),
207
- ShiftLeft => Some(BinOpKind::Shl),
208
- ShiftRight => Some(BinOpKind::Shr),
209
- BitAnd => Some(BinOpKind::BitAnd),
210
- BitXor => Some(BinOpKind::BitXor),
211
- BitOr => Some(BinOpKind::BitOr),
212
- LAnd => Some(BinOpKind::And),
213
- LOr => Some(BinOpKind::Or),
214
- Assign | AssignOp(_) | As | DotDot | DotDotEq => None,
113
+ As | Binary(_) | DotDot | DotDotEq => false,
215
114
}
216
115
}
217
116
@@ -221,16 +120,19 @@ impl AssocOp {
221
120
/// parentheses while having a high degree of confidence on the correctness of the suggestion.
222
121
pub fn can_continue_expr_unambiguously(&self) -> bool {
223
122
use AssocOp::*;
123
+ use BinOpKind::*;
224
124
matches!(
225
125
self,
226
- BitXor | // `{ 42 } ^ 3`
227
126
Assign | // `{ 42 } = { 42 }`
228
- Divide | // `{ 42 } / 42`
229
- Modulus | // `{ 42 } % 2`
230
- ShiftRight | // `{ 42 } >> 2`
231
- LessEqual | // `{ 42 } <= 3`
232
- Greater | // `{ 42 } > 3`
233
- GreaterEqual | // `{ 42 } >= 3`
127
+ Binary(
128
+ BitXor | // `{ 42 } ^ 3`
129
+ Div | // `{ 42 } / 42`
130
+ Rem | // `{ 42 } % 2`
131
+ Shr | // `{ 42 } >> 2`
132
+ Le | // `{ 42 } <= 3`
133
+ Gt | // `{ 42 } > 3`
134
+ Ge // `{ 42 } >= 3`
135
+ ) |
234
136
AssignOp(_) | // `{ 42 } +=`
235
137
// Equal | // `{ 42 } == { 42 }` Accepting these here would regress incorrect
236
138
// NotEqual | // `{ 42 } != { 42 } struct literals parser recovery.
0 commit comments