1
Fork 0

Remove LhsExpr.

`parse_expr_assoc_with` has an awkward structure -- sometimes the lhs is
already parsed. This commit splits the post-lhs part into a new method
`parse_expr_assoc_rest_with`, which makes everything shorter and
simpler.
This commit is contained in:
Nicholas Nethercote 2024-07-31 12:56:25 +10:00
parent 281c2fd5bf
commit fe647f0538
3 changed files with 28 additions and 42 deletions

View file

@ -40,14 +40,6 @@ use super::{
};
use crate::{errors, maybe_recover_from_interpolated_ty_qpath};
#[derive(Debug)]
pub(super) enum LhsExpr {
// Already parsed just the outer attributes.
Unparsed { attrs: AttrWrapper },
// Already parsed the expression.
Parsed { expr: P<Expr>, starts_statement: bool },
}
#[derive(Debug)]
enum DestructuredFloat {
/// 1e2
@ -113,30 +105,31 @@ impl<'a> Parser<'a> {
r: Restrictions,
attrs: AttrWrapper,
) -> PResult<'a, P<Expr>> {
self.with_res(r, |this| this.parse_expr_assoc_with(0, LhsExpr::Unparsed { attrs }))
self.with_res(r, |this| this.parse_expr_assoc_with(0, attrs))
}
/// Parses an associative expression with operators of at least `min_prec` precedence.
pub(super) fn parse_expr_assoc_with(
&mut self,
min_prec: usize,
lhs: LhsExpr,
attrs: AttrWrapper,
) -> PResult<'a, P<Expr>> {
let mut starts_stmt = false;
let mut lhs = match lhs {
LhsExpr::Parsed { expr, starts_statement } => {
starts_stmt = starts_statement;
expr
}
LhsExpr::Unparsed { attrs } => {
if self.token.is_range_separator() {
return self.parse_expr_prefix_range(attrs);
} else {
self.parse_expr_prefix(attrs)?
}
}
let lhs = if self.token.is_range_separator() {
return self.parse_expr_prefix_range(attrs);
} else {
self.parse_expr_prefix(attrs)?
};
self.parse_expr_assoc_rest_with(min_prec, false, lhs)
}
/// Parses the rest of an associative expression (i.e. the part after the lhs) with operators
/// of at least `min_prec` precedence.
pub(super) fn parse_expr_assoc_rest_with(
&mut self,
min_prec: usize,
starts_stmt: bool,
mut lhs: P<Expr>,
) -> PResult<'a, P<Expr>> {
if !self.should_continue_as_assoc_expr(&lhs) {
return Ok(lhs);
}
@ -272,7 +265,7 @@ impl<'a> Parser<'a> {
};
let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
let attrs = this.parse_outer_attributes()?;
this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::Unparsed { attrs })
this.parse_expr_assoc_with(prec + prec_adjustment, attrs)
})?;
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
@ -447,7 +440,7 @@ impl<'a> Parser<'a> {
let maybe_lt = self.token.clone();
let attrs = self.parse_outer_attributes()?;
Some(
self.parse_expr_assoc_with(prec + 1, LhsExpr::Unparsed { attrs })
self.parse_expr_assoc_with(prec + 1, attrs)
.map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
)
} else {
@ -504,12 +497,9 @@ impl<'a> Parser<'a> {
let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
// RHS must be parsed with more associativity than the dots.
let attrs = this.parse_outer_attributes()?;
this.parse_expr_assoc_with(
op.unwrap().precedence() + 1,
LhsExpr::Unparsed { attrs },
)
.map(|x| (lo.to(x.span), Some(x)))
.map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
this.parse_expr_assoc_with(op.unwrap().precedence() + 1, attrs)
.map(|x| (lo.to(x.span), Some(x)))
.map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
} else {
(lo, None)
};
@ -2645,10 +2635,7 @@ impl<'a> Parser<'a> {
self.expect(&token::Eq)?;
}
let attrs = self.parse_outer_attributes()?;
let expr = self.parse_expr_assoc_with(
1 + prec_let_scrutinee_needs_par(),
LhsExpr::Unparsed { attrs },
)?;
let expr = self.parse_expr_assoc_with(1 + prec_let_scrutinee_needs_par(), attrs)?;
let span = lo.to(expr.span);
Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span, recovered)))
}