Skip to content

Commit

Permalink
Merge pull request #1647 from dtolnay/classify
Browse files Browse the repository at this point in the history
Create a module for expr classification functions
  • Loading branch information
dtolnay committed May 11, 2024
2 parents 55205b6 + 4843c05 commit b2a7ac8
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 59 deletions.
45 changes: 45 additions & 0 deletions src/classify.rs
@@ -0,0 +1,45 @@
use crate::expr::Expr;

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
match expr {
Expr::If(_)
| Expr::Match(_)
| Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc
| Expr::While(_)
| Expr::Loop(_)
| Expr::ForLoop(_)
| Expr::TryBlock(_)
| Expr::Const(_) => false,
Expr::Array(_)
| Expr::Assign(_)
| Expr::Async(_)
| Expr::Await(_)
| Expr::Binary(_)
| Expr::Break(_)
| Expr::Call(_)
| Expr::Cast(_)
| Expr::Closure(_)
| Expr::Continue(_)
| Expr::Field(_)
| Expr::Group(_)
| Expr::Index(_)
| Expr::Infer(_)
| Expr::Let(_)
| Expr::Lit(_)
| Expr::Macro(_)
| Expr::MethodCall(_)
| Expr::Paren(_)
| Expr::Path(_)
| Expr::Range(_)
| Expr::Reference(_)
| Expr::Repeat(_)
| Expr::Return(_)
| Expr::Struct(_)
| Expr::Try(_)
| Expr::Tuple(_)
| Expr::Unary(_)
| Expr::Yield(_)
| Expr::Verbatim(_) => true
}
}
70 changes: 14 additions & 56 deletions src/expr.rs
Expand Up @@ -1099,52 +1099,6 @@ ast_enum! {
}
}

#[cfg(any(feature = "parsing", feature = "printing"))]
#[cfg(feature = "full")]
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
match expr {
Expr::If(_)
| Expr::Match(_)
| Expr::Block(_) | Expr::Unsafe(_) // both under ExprKind::Block in rustc
| Expr::While(_)
| Expr::Loop(_)
| Expr::ForLoop(_)
| Expr::TryBlock(_)
| Expr::Const(_) => false,
Expr::Array(_)
| Expr::Assign(_)
| Expr::Async(_)
| Expr::Await(_)
| Expr::Binary(_)
| Expr::Break(_)
| Expr::Call(_)
| Expr::Cast(_)
| Expr::Closure(_)
| Expr::Continue(_)
| Expr::Field(_)
| Expr::Group(_)
| Expr::Index(_)
| Expr::Infer(_)
| Expr::Let(_)
| Expr::Lit(_)
| Expr::Macro(_)
| Expr::MethodCall(_)
| Expr::Paren(_)
| Expr::Path(_)
| Expr::Range(_)
| Expr::Reference(_)
| Expr::Repeat(_)
| Expr::Return(_)
| Expr::Struct(_)
| Expr::Try(_)
| Expr::Tuple(_)
| Expr::Unary(_)
| Expr::Yield(_)
| Expr::Verbatim(_) => true
}
}

#[cfg(feature = "parsing")]
mod precedence {
use super::BinOp;
Expand Down Expand Up @@ -1225,14 +1179,16 @@ pub(crate) mod parsing {
#[cfg(feature = "full")]
use crate::attr;
use crate::attr::Attribute;
#[cfg(feature = "full")]
use crate::classify;
use crate::error::{Error, Result};
use crate::expr::precedence::Precedence;
#[cfg(feature = "full")]
use crate::expr::{
requires_terminator, Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock,
ExprBreak, ExprClosure, ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet,
ExprLoop, ExprMatch, ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple,
ExprUnsafe, ExprWhile, ExprYield, Label, RangeLimits,
Arm, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile,
ExprYield, Label, RangeLimits,
};
use crate::expr::{
Expr, ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
Expand Down Expand Up @@ -3005,7 +2961,7 @@ pub(crate) mod parsing {
fat_arrow_token: input.parse()?,
body: {
let body = Expr::parse_with_earlier_boundary_rule(input)?;
requires_comma = requires_terminator(&body);
requires_comma = classify::requires_terminator(&body);
Box::new(body)
},
comma: {
Expand Down Expand Up @@ -3109,11 +3065,13 @@ pub(crate) mod printing {
#[cfg(feature = "full")]
use crate::attr::FilterAttrs;
#[cfg(feature = "full")]
use crate::classify;
#[cfg(feature = "full")]
use crate::expr::{
requires_terminator, Arm, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock,
ExprBreak, ExprClosure, ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet,
ExprLoop, ExprMatch, ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple,
ExprUnsafe, ExprWhile, ExprYield, Label, RangeLimits,
Arm, Expr, ExprArray, ExprAssign, ExprAsync, ExprAwait, ExprBlock, ExprBreak, ExprClosure,
ExprConst, ExprContinue, ExprForLoop, ExprIf, ExprInfer, ExprLet, ExprLoop, ExprMatch,
ExprRange, ExprRepeat, ExprReturn, ExprTry, ExprTryBlock, ExprTuple, ExprUnsafe, ExprWhile,
ExprYield, Label, RangeLimits,
};
use crate::expr::{
ExprBinary, ExprCall, ExprCast, ExprField, ExprGroup, ExprIndex, ExprLit, ExprMacro,
Expand Down Expand Up @@ -3442,7 +3400,7 @@ 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 && requires_terminator(&arm.body) && arm.comma.is_none() {
if !is_last && classify::requires_terminator(&arm.body) && arm.comma.is_none() {
<Token![,]>::default().to_tokens(tokens);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/lib.rs
Expand Up @@ -327,6 +327,10 @@ mod bigint;
#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
pub mod buffer;

#[cfg(any(feature = "parsing", feature = "printing"))]
#[cfg(feature = "full")]
mod classify;

mod custom_keyword;

mod custom_punctuation;
Expand Down
7 changes: 4 additions & 3 deletions src/stmt.rs
Expand Up @@ -80,8 +80,9 @@ ast_struct! {
#[cfg(feature = "parsing")]
pub(crate) mod parsing {
use crate::attr::Attribute;
use crate::classify;
use crate::error::Result;
use crate::expr::{self, Expr, ExprBlock, ExprMacro};
use crate::expr::{Expr, ExprBlock, ExprMacro};
use crate::ident::Ident;
use crate::item;
use crate::mac::{self, Macro};
Expand Down Expand Up @@ -158,7 +159,7 @@ pub(crate) mod parsing {
}
let stmt = parse_stmt(input, AllowNoSemi(true))?;
let requires_semicolon = match &stmt {
Stmt::Expr(stmt, None) => expr::requires_terminator(stmt),
Stmt::Expr(stmt, None) => classify::requires_terminator(stmt),
Stmt::Macro(stmt) => {
stmt.semi_token.is_none() && !stmt.mac.delimiter.is_brace()
}
Expand Down Expand Up @@ -400,7 +401,7 @@ pub(crate) mod parsing {

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

0 comments on commit b2a7ac8

Please sign in to comment.