Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Choose range bailouts based on precedence #1837

Merged
merged 1 commit into from
Jan 10, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 52 additions & 47 deletions src/fixup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ impl FixupContext {
fn leftmost_subexpression_precedence(self, expr: &Expr) -> Precedence {
#[cfg(feature = "full")]
if !self.next_operator_can_begin_expr || self.next_operator == Precedence::Range {
if let Scan::Bailout = scan_right(expr, self, false, 0, 0) {
if let Scan::Bailout = scan_right(expr, self, Precedence::MIN, 0, 0) {
if scan_left(expr, self) {
return Precedence::Unambiguous;
}
Expand Down Expand Up @@ -354,13 +354,8 @@ impl FixupContext {
if default_prec < Precedence::Prefix
&& (!self.next_operator_can_begin_expr || self.next_operator == Precedence::Range)
{
if let Scan::Bailout | Scan::Fail = scan_right(
expr,
self,
self.previous_operator == Precedence::Range,
1,
0,
) {
if let Scan::Bailout | Scan::Fail = scan_right(expr, self, self.previous_operator, 1, 0)
{
if scan_left(expr, self) {
return Precedence::Prefix;
}
Expand Down Expand Up @@ -467,6 +462,13 @@ impl Clone for Scan {
}
}

#[cfg(feature = "full")]
impl PartialEq for Scan {
fn eq(&self, other: &Self) -> bool {
*self as u8 == *other as u8
}
}

#[cfg(feature = "full")]
fn scan_left(expr: &Expr, fixup: FixupContext) -> bool {
match expr {
Expand All @@ -485,12 +487,21 @@ fn scan_left(expr: &Expr, fixup: FixupContext) -> bool {
fn scan_right(
expr: &Expr,
fixup: FixupContext,
range: bool,
precedence: Precedence,
fail_offset: u8,
bailout_offset: u8,
) -> Scan {
let consume_by_precedence = if match precedence {
Precedence::Assign | Precedence::Compare => precedence <= fixup.next_operator,
_ => precedence < fixup.next_operator,
} || fixup.next_operator == Precedence::MIN
{
Scan::Consume
} else {
Scan::Bailout
};
if fixup.parenthesize(expr) {
return Scan::Consume;
return consume_by_precedence;
}
match expr {
Expr::Assign(e) => {
Expand All @@ -504,7 +515,7 @@ fn scan_right(
let scan = scan_right(
&e.right,
right_fixup,
false,
Precedence::Assign,
match fixup.next_operator {
Precedence::Unambiguous => fail_offset,
_ => 1,
Expand All @@ -521,7 +532,10 @@ fn scan_right(
}
Expr::Binary(e) => {
if match fixup.next_operator {
Precedence::Unambiguous => fail_offset >= 2,
Precedence::Unambiguous => {
fail_offset >= 2
&& (consume_by_precedence == Scan::Consume || bailout_offset >= 1)
}
_ => bailout_offset >= 1,
} {
return Scan::Consume;
Expand All @@ -531,29 +545,22 @@ fn scan_right(
let scan = scan_right(
&e.right,
right_fixup,
range && binop_prec != Precedence::Assign,
binop_prec,
match fixup.next_operator {
Precedence::Unambiguous => fail_offset,
_ => 1,
},
match (binop_prec, fixup.next_operator) {
(Precedence::Assign, _) => 1,
(_, Precedence::Assign | Precedence::Range) if range => 0,
_ => 1,
},
consume_by_precedence as u8 - Scan::Bailout as u8,
);
if match (scan, fixup.next_operator) {
(Scan::Fail, _) => false,
(Scan::Bailout, _) if binop_prec == Precedence::Assign => true,
(Scan::Bailout, Precedence::Assign | Precedence::Range) => !range,
(Scan::Bailout | Scan::Consume, _) => true,
} {
return Scan::Consume;
match scan {
Scan::Fail => {}
Scan::Bailout => return consume_by_precedence,
Scan::Consume => return Scan::Consume,
}
let right_needs_group = binop_prec != Precedence::Assign
&& right_fixup.rightmost_subexpression_precedence(&e.right) <= binop_prec;
if right_needs_group {
Scan::Consume
consume_by_precedence
} else if let (Scan::Fail, Precedence::Unambiguous) = (scan, fixup.next_operator) {
Scan::Fail
} else {
Expand All @@ -564,7 +571,10 @@ fn scan_right(
| Expr::Reference(ExprReference { expr, .. })
| Expr::Unary(ExprUnary { expr, .. }) => {
if match fixup.next_operator {
Precedence::Unambiguous => fail_offset >= 2,
Precedence::Unambiguous => {
fail_offset >= 2
&& (consume_by_precedence == Scan::Consume || bailout_offset >= 1)
}
_ => bailout_offset >= 1,
} {
return Scan::Consume;
Expand All @@ -573,25 +583,20 @@ fn scan_right(
let scan = scan_right(
expr,
right_fixup,
range,
precedence,
match fixup.next_operator {
Precedence::Unambiguous => fail_offset,
_ => 1,
},
match fixup.next_operator {
Precedence::Assign | Precedence::Range if range => 0,
_ => 1,
},
consume_by_precedence as u8 - Scan::Bailout as u8,
);
if match (scan, fixup.next_operator) {
(Scan::Fail, _) => false,
(Scan::Bailout, Precedence::Assign | Precedence::Range) => !range,
(Scan::Bailout | Scan::Consume, _) => true,
} {
return Scan::Consume;
match scan {
Scan::Fail => {}
Scan::Bailout => return consume_by_precedence,
Scan::Consume => return Scan::Consume,
}
if right_fixup.rightmost_subexpression_precedence(expr) < Precedence::Prefix {
Scan::Consume
consume_by_precedence
} else if let (Scan::Fail, Precedence::Unambiguous) = (scan, fixup.next_operator) {
Scan::Fail
} else {
Expand All @@ -608,7 +613,7 @@ fn scan_right(
let scan = scan_right(
end,
right_fixup,
true,
Precedence::Range,
fail_offset,
match fixup.next_operator {
Precedence::Assign | Precedence::Range => 0,
Expand Down Expand Up @@ -639,13 +644,13 @@ fn scan_right(
return Scan::Consume;
}
let right_fixup = fixup.rightmost_subexpression_fixup(true, true, Precedence::Jump);
match scan_right(value, right_fixup, false, 1, 1) {
match scan_right(value, right_fixup, Precedence::Jump, 1, 1) {
Scan::Fail => Scan::Bailout,
Scan::Bailout | Scan::Consume => Scan::Consume,
}
}
None => match fixup.next_operator {
Precedence::Assign if range => Scan::Fail,
Precedence::Assign if precedence > Precedence::Assign => Scan::Fail,
_ => Scan::Consume,
},
},
Expand All @@ -656,13 +661,13 @@ fn scan_right(
}
let right_fixup =
fixup.rightmost_subexpression_fixup(true, false, Precedence::Jump);
match scan_right(e, right_fixup, false, 1, 1) {
match scan_right(e, right_fixup, Precedence::Jump, 1, 1) {
Scan::Fail => Scan::Bailout,
Scan::Bailout | Scan::Consume => Scan::Consume,
}
}
None => match fixup.next_operator {
Precedence::Assign if range => Scan::Fail,
Precedence::Assign if precedence > Precedence::Assign => Scan::Fail,
_ => Scan::Consume,
},
},
Expand All @@ -675,7 +680,7 @@ fn scan_right(
}
let right_fixup =
fixup.rightmost_subexpression_fixup(false, false, Precedence::Jump);
match scan_right(&e.body, right_fixup, false, 1, 1) {
match scan_right(&e.body, right_fixup, Precedence::Jump, 1, 1) {
Scan::Fail => Scan::Bailout,
Scan::Bailout | Scan::Consume => Scan::Consume,
}
Expand Down Expand Up @@ -713,8 +718,8 @@ fn scan_right(
| Expr::Unsafe(_)
| Expr::Verbatim(_)
| Expr::While(_) => match fixup.next_operator {
Precedence::Assign | Precedence::Range if range => Scan::Fail,
_ => Scan::Consume,
Precedence::Assign | Precedence::Range if precedence == Precedence::Range => Scan::Fail,
_ => consume_by_precedence,
},
}
}
Loading