Introduce AssocOp::Binary
.
It mirrors `ExprKind::Binary`, and contains a `BinOpKind`. This makes `AssocOp` more like `ExprKind`. Note that the variants removed from `AssocOp` are all named differently to `BinOpToken`, e.g. `Multiply` instead of `Mul`, so that's an inconsistency removed. The commit adds `precedence` and `fixity` methods to `BinOpKind`, and calls them from the corresponding methods in `AssocOp`. This avoids the need to create an `AssocOp` from a `BinOpKind` in a bunch of places, and `AssocOp::from_ast_binop` is removed. `AssocOp::to_ast_binop` is also no longer needed. Overall things are shorter and nicer.
This commit is contained in:
parent
a8364f3b2a
commit
ceafbad81f
10 changed files with 152 additions and 256 deletions
|
@ -1350,13 +1350,13 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
return match (op.node, &outer_op.node) {
|
||||
// `x == y == z`
|
||||
(BinOpKind::Eq, AssocOp::Equal) |
|
||||
(BinOpKind::Eq, AssocOp::Binary(BinOpKind::Eq)) |
|
||||
// `x < y < z` and friends.
|
||||
(BinOpKind::Lt, AssocOp::Less | AssocOp::LessEqual) |
|
||||
(BinOpKind::Le, AssocOp::LessEqual | AssocOp::Less) |
|
||||
(BinOpKind::Lt, AssocOp::Binary(BinOpKind::Lt | BinOpKind::Le)) |
|
||||
(BinOpKind::Le, AssocOp::Binary(BinOpKind::Lt | BinOpKind::Le)) |
|
||||
// `x > y > z` and friends.
|
||||
(BinOpKind::Gt, AssocOp::Greater | AssocOp::GreaterEqual) |
|
||||
(BinOpKind::Ge, AssocOp::GreaterEqual | AssocOp::Greater) => {
|
||||
(BinOpKind::Gt, AssocOp::Binary(BinOpKind::Gt | BinOpKind::Ge)) |
|
||||
(BinOpKind::Ge, AssocOp::Binary(BinOpKind::Gt | BinOpKind::Ge)) => {
|
||||
let expr_to_str = |e: &Expr| {
|
||||
self.span_to_snippet(e.span)
|
||||
.unwrap_or_else(|_| pprust::expr_to_string(e))
|
||||
|
@ -1368,7 +1368,10 @@ impl<'a> Parser<'a> {
|
|||
false // Keep the current parse behavior, where the AST is `(x < y) < z`.
|
||||
}
|
||||
// `x == y < z`
|
||||
(BinOpKind::Eq, AssocOp::Less | AssocOp::LessEqual | AssocOp::Greater | AssocOp::GreaterEqual) => {
|
||||
(
|
||||
BinOpKind::Eq,
|
||||
AssocOp::Binary(BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge)
|
||||
) => {
|
||||
// Consume `z`/outer-op-rhs.
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
match self.parse_expr() {
|
||||
|
@ -1389,7 +1392,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
// `x > y == z`
|
||||
(BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge, AssocOp::Equal) => {
|
||||
(
|
||||
BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge,
|
||||
AssocOp::Binary(BinOpKind::Eq)
|
||||
) => {
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
// At this point it is always valid to enclose the lhs in parentheses, no
|
||||
// further checks are necessary.
|
||||
|
@ -1457,10 +1463,10 @@ impl<'a> Parser<'a> {
|
|||
|
||||
// Include `<` to provide this recommendation even in a case like
|
||||
// `Foo<Bar<Baz<Qux, ()>>>`
|
||||
if op.node == BinOpKind::Lt && outer_op.node == AssocOp::Less
|
||||
|| outer_op.node == AssocOp::Greater
|
||||
if op.node == BinOpKind::Lt && outer_op.node == AssocOp::Binary(BinOpKind::Lt)
|
||||
|| outer_op.node == AssocOp::Binary(BinOpKind::Gt)
|
||||
{
|
||||
if outer_op.node == AssocOp::Less {
|
||||
if outer_op.node == AssocOp::Binary(BinOpKind::Lt) {
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
self.bump();
|
||||
// So far we have parsed `foo<bar<`, consume the rest of the type args.
|
||||
|
@ -2635,10 +2641,12 @@ impl<'a> Parser<'a> {
|
|||
) -> PResult<'a, GenericArg> {
|
||||
let is_op_or_dot = AssocOp::from_token(&self.token)
|
||||
.and_then(|op| {
|
||||
if let AssocOp::Greater
|
||||
| AssocOp::Less
|
||||
| AssocOp::ShiftRight
|
||||
| AssocOp::GreaterEqual
|
||||
if let AssocOp::Binary(
|
||||
BinOpKind::Gt
|
||||
| BinOpKind::Lt
|
||||
| BinOpKind::Shr
|
||||
| BinOpKind::Ge
|
||||
)
|
||||
// Don't recover from `foo::<bar = baz>`, because this could be an attempt to
|
||||
// assign a value to a defaulted generic parameter.
|
||||
| AssocOp::Assign
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue