Skip to content

Commit

Permalink
Differentiate statement boundary rules for stmt vs match arm
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed May 16, 2024
1 parent 9cb0f98 commit bab4cae
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
10 changes: 8 additions & 2 deletions src/classify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ use crate::ty::{ReturnType, Type};
use proc_macro2::{Delimiter, TokenStream, TokenTree};
use std::ops::ControlFlow;

pub(crate) fn requires_terminator(expr: &Expr) -> bool {
// see https://github.com/rust-lang/rust/blob/9a19e7604/compiler/rustc_ast/src/util/classify.rs#L7-L26
pub(crate) fn requires_semi_to_be_stmt(expr: &Expr) -> bool {
match expr {
Expr::Macro(expr) => !expr.mac.delimiter.is_brace(),
_ => requires_comma_to_be_match_arm(expr),
}
}

pub(crate) fn requires_comma_to_be_match_arm(expr: &Expr) -> bool {
match expr {
Expr::If(_)
| Expr::Match(_)
Expand Down
7 changes: 5 additions & 2 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2873,7 +2873,7 @@ pub(crate) mod parsing {
fat_arrow_token: input.parse()?,
body: {
let body = Expr::parse_with_earlier_boundary_rule(input)?;
requires_comma = classify::requires_terminator(&body);
requires_comma = classify::requires_comma_to_be_match_arm(&body);
Box::new(body)
},
comma: {
Expand Down Expand Up @@ -3312,7 +3312,10 @@ pub(crate) mod printing {
// Ensure that we have a comma after a non-block arm, except
// for the last one.
let is_last = i == self.arms.len() - 1;
if !is_last && classify::requires_terminator(&arm.body) && arm.comma.is_none() {
if !is_last
&& classify::requires_comma_to_be_match_arm(&arm.body)
&& arm.comma.is_none()
{
<Token![,]>::default().to_tokens(tokens);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ pub(crate) mod parsing {
}
let stmt = parse_stmt(input, AllowNoSemi(true))?;
let requires_semicolon = match &stmt {
Stmt::Expr(stmt, None) => classify::requires_terminator(stmt),
Stmt::Expr(stmt, None) => classify::requires_semi_to_be_stmt(stmt),
Stmt::Macro(stmt) => {
stmt.semi_token.is_none() && !stmt.mac.delimiter.is_brace()
}
Expand Down Expand Up @@ -401,7 +401,7 @@ pub(crate) mod parsing {

if semi_token.is_some() {
Ok(Stmt::Expr(e, semi_token))
} else if allow_nosemi.0 || !classify::requires_terminator(&e) {
} else if allow_nosemi.0 || !classify::requires_semi_to_be_stmt(&e) {
Ok(Stmt::Expr(e, None))
} else {
Err(input.error("expected semicolon"))
Expand Down

0 comments on commit bab4cae

Please sign in to comment.