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:
parent
281c2fd5bf
commit
fe647f0538
@ -40,14 +40,6 @@
|
|||||||
};
|
};
|
||||||
use crate::{errors, maybe_recover_from_interpolated_ty_qpath};
|
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)]
|
#[derive(Debug)]
|
||||||
enum DestructuredFloat {
|
enum DestructuredFloat {
|
||||||
/// 1e2
|
/// 1e2
|
||||||
@ -113,30 +105,31 @@ pub(super) fn parse_expr_res(
|
|||||||
r: Restrictions,
|
r: Restrictions,
|
||||||
attrs: AttrWrapper,
|
attrs: AttrWrapper,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> 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.
|
/// Parses an associative expression with operators of at least `min_prec` precedence.
|
||||||
pub(super) fn parse_expr_assoc_with(
|
pub(super) fn parse_expr_assoc_with(
|
||||||
&mut self,
|
&mut self,
|
||||||
min_prec: usize,
|
min_prec: usize,
|
||||||
lhs: LhsExpr,
|
attrs: AttrWrapper,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
let mut starts_stmt = false;
|
let lhs = if self.token.is_range_separator() {
|
||||||
let mut lhs = match lhs {
|
return self.parse_expr_prefix_range(attrs);
|
||||||
LhsExpr::Parsed { expr, starts_statement } => {
|
} else {
|
||||||
starts_stmt = starts_statement;
|
self.parse_expr_prefix(attrs)?
|
||||||
expr
|
|
||||||
}
|
|
||||||
LhsExpr::Unparsed { attrs } => {
|
|
||||||
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) {
|
if !self.should_continue_as_assoc_expr(&lhs) {
|
||||||
return Ok(lhs);
|
return Ok(lhs);
|
||||||
}
|
}
|
||||||
@ -272,7 +265,7 @@ pub(super) fn parse_expr_assoc_with(
|
|||||||
};
|
};
|
||||||
let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
|
let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
|
||||||
let attrs = this.parse_outer_attributes()?;
|
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);
|
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
|
||||||
@ -447,7 +440,7 @@ fn parse_expr_range(
|
|||||||
let maybe_lt = self.token.clone();
|
let maybe_lt = self.token.clone();
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
Some(
|
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))?,
|
.map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -504,12 +497,9 @@ fn parse_expr_prefix_range(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>
|
|||||||
let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
|
let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() {
|
||||||
// RHS must be parsed with more associativity than the dots.
|
// RHS must be parsed with more associativity than the dots.
|
||||||
let attrs = this.parse_outer_attributes()?;
|
let attrs = this.parse_outer_attributes()?;
|
||||||
this.parse_expr_assoc_with(
|
this.parse_expr_assoc_with(op.unwrap().precedence() + 1, attrs)
|
||||||
op.unwrap().precedence() + 1,
|
.map(|x| (lo.to(x.span), Some(x)))
|
||||||
LhsExpr::Unparsed { attrs },
|
.map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
|
||||||
)
|
|
||||||
.map(|x| (lo.to(x.span), Some(x)))
|
|
||||||
.map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
|
|
||||||
} else {
|
} else {
|
||||||
(lo, None)
|
(lo, None)
|
||||||
};
|
};
|
||||||
@ -2645,10 +2635,7 @@ fn parse_expr_let(&mut self, restrictions: Restrictions) -> PResult<'a, P<Expr>>
|
|||||||
self.expect(&token::Eq)?;
|
self.expect(&token::Eq)?;
|
||||||
}
|
}
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?;
|
||||||
let expr = self.parse_expr_assoc_with(
|
let expr = self.parse_expr_assoc_with(1 + prec_let_scrutinee_needs_par(), attrs)?;
|
||||||
1 + prec_let_scrutinee_needs_par(),
|
|
||||||
LhsExpr::Unparsed { attrs },
|
|
||||||
)?;
|
|
||||||
let span = lo.to(expr.span);
|
let span = lo.to(expr.span);
|
||||||
Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span, recovered)))
|
Ok(self.mk_expr(span, ExprKind::Let(pat, expr, span, recovered)))
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
|
UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
|
||||||
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens,
|
UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens,
|
||||||
};
|
};
|
||||||
use crate::parser::expr::{could_be_unclosed_char_literal, LhsExpr};
|
use crate::parser::expr::could_be_unclosed_char_literal;
|
||||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone)]
|
||||||
@ -403,8 +403,9 @@ fn maybe_recover_trailing_expr(
|
|||||||
|
|
||||||
// Parse an associative expression such as `+ expr`, `% expr`, ...
|
// Parse an associative expression such as `+ expr`, `% expr`, ...
|
||||||
// Assignements, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
|
// Assignements, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
|
||||||
let lhs = LhsExpr::Parsed { expr, starts_statement: false };
|
if let Ok(expr) =
|
||||||
if let Ok(expr) = snapshot.parse_expr_assoc_with(0, lhs).map_err(|err| err.cancel()) {
|
snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel())
|
||||||
|
{
|
||||||
// We got a valid expression.
|
// We got a valid expression.
|
||||||
self.restore_snapshot(snapshot);
|
self.restore_snapshot(snapshot);
|
||||||
self.restrictions.remove(Restrictions::IS_PAT);
|
self.restrictions.remove(Restrictions::IS_PAT);
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
|
|
||||||
use super::attr::InnerAttrForbiddenReason;
|
use super::attr::InnerAttrForbiddenReason;
|
||||||
use super::diagnostics::AttemptLocalParseRecovery;
|
use super::diagnostics::AttemptLocalParseRecovery;
|
||||||
use super::expr::LhsExpr;
|
|
||||||
use super::pat::{PatternLocation, RecoverComma};
|
use super::pat::{PatternLocation, RecoverComma};
|
||||||
use super::path::PathStyle;
|
use super::path::PathStyle;
|
||||||
use super::{
|
use super::{
|
||||||
@ -178,7 +177,7 @@ fn parse_stmt_path_start(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a,
|
|||||||
// Perform this outside of the `collect_tokens_trailing_token` closure,
|
// Perform this outside of the `collect_tokens_trailing_token` closure,
|
||||||
// since our outer attributes do not apply to this part of the expression
|
// since our outer attributes do not apply to this part of the expression
|
||||||
let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
|
let expr = self.with_res(Restrictions::STMT_EXPR, |this| {
|
||||||
this.parse_expr_assoc_with(0, LhsExpr::Parsed { expr, starts_statement: true })
|
this.parse_expr_assoc_rest_with(0, true, expr)
|
||||||
})?;
|
})?;
|
||||||
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Expr(expr)))
|
Ok(self.mk_stmt(lo.to(self.prev_token.span), StmtKind::Expr(expr)))
|
||||||
} else {
|
} else {
|
||||||
@ -211,8 +210,7 @@ fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResu
|
|||||||
let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
|
let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac));
|
||||||
let e = self.maybe_recover_from_bad_qpath(e)?;
|
let e = self.maybe_recover_from_bad_qpath(e)?;
|
||||||
let e = self.parse_expr_dot_or_call_with(attrs, e, lo)?;
|
let e = self.parse_expr_dot_or_call_with(attrs, e, lo)?;
|
||||||
let e = self
|
let e = self.parse_expr_assoc_rest_with(0, false, e)?;
|
||||||
.parse_expr_assoc_with(0, LhsExpr::Parsed { expr: e, starts_statement: false })?;
|
|
||||||
StmtKind::Expr(e)
|
StmtKind::Expr(e)
|
||||||
};
|
};
|
||||||
Ok(self.mk_stmt(lo.to(hi), kind))
|
Ok(self.mk_stmt(lo.to(hi), kind))
|
||||||
|
Loading…
Reference in New Issue
Block a user