From 4843c0513460ffe0e715d17b568545825b723c42 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 11 May 2024 16:02:24 -0700 Subject: [PATCH] Create a module for expr classification functions --- src/classify.rs | 45 +++++++++++++++++++++++++++++++ src/expr.rs | 70 ++++++++++--------------------------------------- src/lib.rs | 4 +++ src/stmt.rs | 7 ++--- 4 files changed, 67 insertions(+), 59 deletions(-) create mode 100644 src/classify.rs diff --git a/src/classify.rs b/src/classify.rs new file mode 100644 index 0000000000..3d516af0ff --- /dev/null +++ b/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 + } +} diff --git a/src/expr.rs b/src/expr.rs index 265316a466..107f670c38 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -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; @@ -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, @@ -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: { @@ -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, @@ -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() { ::default().to_tokens(tokens); } } diff --git a/src/lib.rs b/src/lib.rs index 2bdf0afe7e..481377058c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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; diff --git a/src/stmt.rs b/src/stmt.rs index 8a1bee95f0..15b01bcc5d 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -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}; @@ -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() } @@ -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"))