2014-04-28 02:05:41 +00:00
|
|
|
//! Routines the parser uses to classify AST nodes
|
|
|
|
|
|
|
|
// Predicates on exprs and stmts that the pretty-printer and parser use
|
2012-05-22 17:54:12 +00:00
|
|
|
|
2019-02-06 17:33:01 +00:00
|
|
|
use crate::ast;
|
2012-04-18 05:02:00 +00:00
|
|
|
|
2014-06-09 20:12:30 +00:00
|
|
|
/// Does this expression require a semicolon to be treated
|
|
|
|
/// as a statement? The negation of this: 'can this expression
|
|
|
|
/// be used as a statement without a semicolon' -- is used
|
|
|
|
/// as an early-bail-out in the parser so that, for instance,
|
|
|
|
/// if true {...} else {...}
|
|
|
|
/// |x| 5
|
|
|
|
/// isn't parsed as (if true {...} else {...} | x) | 5
|
2014-09-13 16:06:01 +00:00
|
|
|
pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool {
|
2020-12-24 01:55:21 +00:00
|
|
|
!matches!(
|
|
|
|
e.kind,
|
2016-02-08 15:05:05 +00:00
|
|
|
ast::ExprKind::If(..)
|
2020-12-24 01:55:21 +00:00
|
|
|
| ast::ExprKind::Match(..)
|
|
|
|
| ast::ExprKind::Block(..)
|
|
|
|
| ast::ExprKind::While(..)
|
|
|
|
| ast::ExprKind::Loop(..)
|
|
|
|
| ast::ExprKind::ForLoop(..)
|
|
|
|
| ast::ExprKind::TryBlock(..)
|
2022-12-01 17:54:50 +00:00
|
|
|
| ast::ExprKind::ConstBlock(..)
|
2020-12-24 01:55:21 +00:00
|
|
|
)
|
2012-04-18 05:02:00 +00:00
|
|
|
}
|
2021-07-30 22:12:11 +00:00
|
|
|
|
|
|
|
/// If an expression ends with `}`, returns the innermost expression ending in the `}`
|
|
|
|
pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
|
|
|
|
use ast::ExprKind::*;
|
|
|
|
|
|
|
|
loop {
|
|
|
|
match &expr.kind {
|
|
|
|
AddrOf(_, _, e)
|
|
|
|
| Assign(_, e, _)
|
|
|
|
| AssignOp(_, _, e)
|
|
|
|
| Binary(_, _, e)
|
|
|
|
| Box(e)
|
|
|
|
| Break(_, Some(e))
|
|
|
|
| Let(_, e, _)
|
|
|
|
| Range(_, Some(e), _)
|
|
|
|
| Ret(Some(e))
|
|
|
|
| Unary(_, e)
|
|
|
|
| Yield(Some(e)) => {
|
|
|
|
expr = e;
|
|
|
|
}
|
2022-09-08 00:52:51 +00:00
|
|
|
Closure(closure) => {
|
|
|
|
expr = &closure.body;
|
|
|
|
}
|
2021-07-30 22:12:11 +00:00
|
|
|
Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..)
|
|
|
|
| TryBlock(..) | While(..) => break Some(expr),
|
|
|
|
_ => break None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|