Refactor LhsExpr
.
Combine `NotYetParsed` and `AttributesParsed` into a single variant, because (a) that reflects the structure of the code that consumes `LhsExpr`, and (b) because that variant will have the `Option` removed in a later commit.
This commit is contained in:
parent
42e47dfe82
commit
25523ba382
3 changed files with 38 additions and 42 deletions
|
@ -70,9 +70,10 @@ macro_rules! maybe_whole_expr {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) enum LhsExpr {
|
pub(super) enum LhsExpr {
|
||||||
NotYetParsed,
|
// Already parsed either (a) nothing or (b) just the outer attributes.
|
||||||
AttributesParsed(AttrWrapper),
|
Unparsed { attrs: Option<AttrWrapper> },
|
||||||
AlreadyParsed { expr: P<Expr>, starts_statement: bool },
|
// Already parsed the expression.
|
||||||
|
Parsed { expr: P<Expr>, starts_statement: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -133,9 +134,9 @@ impl<'a> Parser<'a> {
|
||||||
pub(super) fn parse_expr_res(
|
pub(super) fn parse_expr_res(
|
||||||
&mut self,
|
&mut self,
|
||||||
r: Restrictions,
|
r: Restrictions,
|
||||||
already_parsed_attrs: Option<AttrWrapper>,
|
attrs: Option<AttrWrapper>,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
self.with_res(r, |this| this.parse_expr_assoc(already_parsed_attrs))
|
self.with_res(r, |this| this.parse_expr_assoc(attrs))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an associative expression.
|
/// Parses an associative expression.
|
||||||
|
@ -143,15 +144,8 @@ impl<'a> Parser<'a> {
|
||||||
/// This parses an expression accounting for associativity and precedence of the operators in
|
/// This parses an expression accounting for associativity and precedence of the operators in
|
||||||
/// the expression.
|
/// the expression.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn parse_expr_assoc(
|
fn parse_expr_assoc(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
|
||||||
&mut self,
|
self.parse_expr_assoc_with(0, LhsExpr::Unparsed { attrs })
|
||||||
already_parsed_attrs: Option<AttrWrapper>,
|
|
||||||
) -> PResult<'a, P<Expr>> {
|
|
||||||
let lhs = match already_parsed_attrs {
|
|
||||||
Some(attrs) => LhsExpr::AttributesParsed(attrs),
|
|
||||||
None => LhsExpr::NotYetParsed,
|
|
||||||
};
|
|
||||||
self.parse_expr_assoc_with(0, lhs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses an associative expression with operators of at least `min_prec` precedence.
|
/// Parses an associative expression with operators of at least `min_prec` precedence.
|
||||||
|
@ -161,18 +155,17 @@ impl<'a> Parser<'a> {
|
||||||
lhs: LhsExpr,
|
lhs: LhsExpr,
|
||||||
) -> PResult<'a, P<Expr>> {
|
) -> PResult<'a, P<Expr>> {
|
||||||
let mut starts_stmt = false;
|
let mut starts_stmt = false;
|
||||||
let mut lhs = if let LhsExpr::AlreadyParsed { expr, starts_statement } = lhs {
|
let mut lhs = match lhs {
|
||||||
starts_stmt = starts_statement;
|
LhsExpr::Parsed { expr, starts_statement } => {
|
||||||
expr
|
starts_stmt = starts_statement;
|
||||||
} else {
|
expr
|
||||||
let attrs = match lhs {
|
}
|
||||||
LhsExpr::AttributesParsed(attrs) => Some(attrs),
|
LhsExpr::Unparsed { attrs } => {
|
||||||
_ => None,
|
if self.token.is_range_separator() {
|
||||||
};
|
return self.parse_expr_prefix_range(attrs);
|
||||||
if self.token.is_range_separator() {
|
} else {
|
||||||
return self.parse_expr_prefix_range(attrs);
|
self.parse_expr_prefix(attrs)?
|
||||||
} else {
|
}
|
||||||
self.parse_expr_prefix(attrs)?
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -310,7 +303,10 @@ impl<'a> Parser<'a> {
|
||||||
Fixity::None => 1,
|
Fixity::None => 1,
|
||||||
};
|
};
|
||||||
let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
|
let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| {
|
||||||
this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed)
|
this.parse_expr_assoc_with(
|
||||||
|
prec + prec_adjustment,
|
||||||
|
LhsExpr::Unparsed { attrs: None },
|
||||||
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
|
let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span);
|
||||||
|
@ -484,7 +480,7 @@ impl<'a> Parser<'a> {
|
||||||
let rhs = if self.is_at_start_of_range_notation_rhs() {
|
let rhs = if self.is_at_start_of_range_notation_rhs() {
|
||||||
let maybe_lt = self.token.clone();
|
let maybe_lt = self.token.clone();
|
||||||
Some(
|
Some(
|
||||||
self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)
|
self.parse_expr_assoc_with(prec + 1, LhsExpr::Unparsed { attrs: None })
|
||||||
.map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
|
.map_err(|err| self.maybe_err_dotdotlt_syntax(maybe_lt, err))?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
@ -539,9 +535,12 @@ impl<'a> Parser<'a> {
|
||||||
this.bump();
|
this.bump();
|
||||||
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.
|
||||||
this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed)
|
this.parse_expr_assoc_with(
|
||||||
.map(|x| (lo.to(x.span), Some(x)))
|
op.unwrap().precedence() + 1,
|
||||||
.map_err(|err| this.maybe_err_dotdotlt_syntax(maybe_lt, err))?
|
LhsExpr::Unparsed { attrs: None },
|
||||||
|
)
|
||||||
|
.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,8 +2644,10 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
self.expect(&token::Eq)?;
|
self.expect(&token::Eq)?;
|
||||||
}
|
}
|
||||||
let expr =
|
let expr = self.parse_expr_assoc_with(
|
||||||
self.parse_expr_assoc_with(1 + prec_let_scrutinee_needs_par(), LhsExpr::NotYetParsed)?;
|
1 + prec_let_scrutinee_needs_par(),
|
||||||
|
LhsExpr::Unparsed { attrs: None },
|
||||||
|
)?;
|
||||||
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)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -398,7 +398,7 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
// 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::AlreadyParsed { expr, starts_statement: false };
|
let lhs = LhsExpr::Parsed { expr, starts_statement: false };
|
||||||
if let Ok(expr) = snapshot.parse_expr_assoc_with(0, lhs).map_err(|err| err.cancel()) {
|
if let Ok(expr) = snapshot.parse_expr_assoc_with(0, lhs).map_err(|err| err.cancel()) {
|
||||||
// We got a valid expression.
|
// We got a valid expression.
|
||||||
self.restore_snapshot(snapshot);
|
self.restore_snapshot(snapshot);
|
||||||
|
|
|
@ -174,10 +174,7 @@ impl<'a> Parser<'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(
|
this.parse_expr_assoc_with(0, LhsExpr::Parsed { expr, starts_statement: true })
|
||||||
0,
|
|
||||||
LhsExpr::AlreadyParsed { expr, starts_statement: true },
|
|
||||||
)
|
|
||||||
})?;
|
})?;
|
||||||
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 {
|
||||||
|
@ -210,10 +207,8 @@ impl<'a> Parser<'a> {
|
||||||
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(e, lo, attrs)?;
|
let e = self.parse_expr_dot_or_call_with(e, lo, attrs)?;
|
||||||
let e = self.parse_expr_assoc_with(
|
let e = self
|
||||||
0,
|
.parse_expr_assoc_with(0, LhsExpr::Parsed { expr: e, starts_statement: false })?;
|
||||||
LhsExpr::AlreadyParsed { 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…
Add table
Add a link
Reference in a new issue