Skip to content

Commit

Permalink
Merge pull request #1741 from dtolnay/binoploop
Browse files Browse the repository at this point in the history
Force cursor to advance in parse_expr calls
  • Loading branch information
dtolnay committed Sep 27, 2024
2 parents 09d020f + 8df4dd0 commit 037861a
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1390,17 +1390,26 @@ pub(crate) mod parsing {
loop {
let next = peek_precedence(input);
if next > precedence || next == precedence && precedence == Precedence::Assign {
let cursor = input.cursor();
rhs = parse_expr(
input,
rhs,
#[cfg(feature = "full")]
allow_struct,
next,
)?;
if cursor == input.cursor() {
// Bespoke grammar restrictions separate from precedence can
// cause parsing to not advance, such as `..a` being
// disallowed in the left-hand side of binary operators,
// even ones that have lower precedence than `..`.
break;
}
} else {
return Ok(Box::new(rhs));
break;
}
}
Ok(Box::new(rhs))
}

fn peek_precedence(input: ParseStream) -> Precedence {
Expand Down
8 changes: 8 additions & 0 deletions tests/test_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,9 +646,17 @@ fn test_assign_range_precedence() {
fn test_chained_comparison() {
// https://github.com/dtolnay/syn/issues/1738
let _ = syn::parse_str::<Expr>("a = a < a <");
let _ = syn::parse_str::<Expr>("a = a .. a ..");
let _ = syn::parse_str::<Expr>("a = a .. a +=");

let err = syn::parse_str::<Expr>("a < a < a").unwrap_err();
assert_eq!("comparison operators cannot be chained", err.to_string());

let err = syn::parse_str::<Expr>("a .. a .. a").unwrap_err();
assert_eq!("unexpected token", err.to_string());

let err = syn::parse_str::<Expr>("a .. a += a").unwrap_err();
assert_eq!("unexpected token", err.to_string());
}

#[test]
Expand Down

0 comments on commit 037861a

Please sign in to comment.