Skip to content

Commit

Permalink
Merge pull request #1544 from dtolnay/nonedelimloop
Browse files Browse the repository at this point in the history
Fix stmt boundary after None-delimited group containing loop
  • Loading branch information
dtolnay authored Dec 11, 2023
2 parents d332928 + 9c99b3f commit 0ddfc27
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 4 deletions.
36 changes: 33 additions & 3 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1915,7 +1915,15 @@ pub(crate) mod parsing {
#[cfg(feature = "full")]
pub(crate) fn expr_early(input: ParseStream) -> Result<Expr> {
let mut attrs = input.call(expr_attrs)?;
let mut expr = if input.peek(Token![if]) {
let mut expr = if input.peek(token::Group) {
let allow_struct = AllowStruct(true);
let atom = expr_group(input, allow_struct)?;
if continue_parsing_early(&atom) {
trailer_helper(input, atom)?
} else {
atom
}
} else if input.peek(Token![if]) {
Expr::If(input.parse()?)
} else if input.peek(Token![while]) {
Expr::While(input.parse()?)
Expand All @@ -1939,13 +1947,16 @@ pub(crate) mod parsing {
atom_labeled(input)?
} else {
let allow_struct = AllowStruct(true);
let mut expr = unary_expr(input, allow_struct)?;
unary_expr(input, allow_struct)?
};

if continue_parsing_early(&expr) {
attrs.extend(expr.replace_attrs(Vec::new()));
expr.replace_attrs(attrs);

let allow_struct = AllowStruct(true);
return parse_expr(input, expr, allow_struct, Precedence::Any);
};
}

if input.peek(Token![.]) && !input.peek(Token![..]) || input.peek(Token![?]) {
expr = trailer_helper(input, expr)?;
Expand All @@ -1962,6 +1973,25 @@ pub(crate) mod parsing {
Ok(expr)
}

#[cfg(feature = "full")]
fn continue_parsing_early(mut expr: &Expr) -> bool {
while let Expr::Group(group) = expr {
expr = &group.expr;
}
match expr {
Expr::If(_)
| Expr::While(_)
| Expr::ForLoop(_)
| Expr::Loop(_)
| Expr::Match(_)
| Expr::TryBlock(_)
| Expr::Unsafe(_)
| Expr::Const(_)
| Expr::Block(_) => false,
_ => true,
}
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for ExprLit {
fn parse(input: ParseStream) -> Result<Self> {
Expand Down
35 changes: 34 additions & 1 deletion tests/test_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,6 @@ fn test_macro_variable_match_arm() {
// mimics the token stream corresponding to `match v { _ => $expr }`
let expr = Group::new(Delimiter::None, quote! { #[a] () });
let tokens = quote!(match v { _ => #expr });

snapshot!(tokens as Expr, @r###"
Expr::Match {
expr: Expr::Path {
Expand Down Expand Up @@ -270,6 +269,40 @@ fn test_macro_variable_match_arm() {
],
}
"###);

let expr = Group::new(Delimiter::None, quote!(loop {} + 1));
let tokens = quote!(match v { _ => #expr });
snapshot!(tokens as Expr, @r###"
Expr::Match {
expr: Expr::Path {
path: Path {
segments: [
PathSegment {
ident: "v",
},
],
},
},
arms: [
Arm {
pat: Pat::Wild,
body: Expr::Group {
expr: Expr::Binary {
left: Expr::Loop {
body: Block {
stmts: [],
},
},
op: BinOp::Add,
right: Expr::Lit {
lit: 1,
},
},
},
},
],
}
"###);
}

// https://github.com/dtolnay/syn/issues/1019
Expand Down

0 comments on commit 0ddfc27

Please sign in to comment.