Inline and remove Parser::parse_expr_dot_or_call_with_.

It only has two call sites, and it extremely similar to
`Parser::parse_expr_dot_or_call_with`, in both name and behaviour. The
only difference is the latter has an `attrs` argument and an
`ensure_sufficient_stack` call. We can pass in an empty `attrs` as
necessary, as is already done at some `parse_expr_dot_or_call_with` call
sites.
This commit is contained in:
Nicholas Nethercote 2024-07-16 16:12:58 +10:00
parent 96cc9c99b2
commit 96b39f1204

View file

@ -792,7 +792,7 @@ impl<'a> Parser<'a> {
let span = cast_expr.span; let span = cast_expr.span;
let with_postfix = self.parse_expr_dot_or_call_with_(cast_expr, span)?; let with_postfix = self.parse_expr_dot_or_call_with(AttrVec::new(), cast_expr, span)?;
// Check if an illegal postfix operator has been added after the cast. // Check if an illegal postfix operator has been added after the cast.
// If the resulting expression is not a cast, it is an illegal postfix operator. // If the resulting expression is not a cast, it is an illegal postfix operator.
@ -883,35 +883,15 @@ impl<'a> Parser<'a> {
pub(super) fn parse_expr_dot_or_call_with( pub(super) fn parse_expr_dot_or_call_with(
&mut self, &mut self,
mut attrs: ast::AttrVec, mut attrs: ast::AttrVec,
e0: P<Expr>, mut e: P<Expr>,
lo: Span, lo: Span,
) -> PResult<'a, P<Expr>> { ) -> PResult<'a, P<Expr>> {
// Stitch the list of outer attributes onto the return value. let res = ensure_sufficient_stack(|| {
// A little bit ugly, but the best way given the current code
// structure
let res = ensure_sufficient_stack(
// this expr demonstrates the recursion it guards against
|| self.parse_expr_dot_or_call_with_(e0, lo),
);
if attrs.is_empty() {
res
} else {
res.map(|expr| {
expr.map(|mut expr| {
attrs.extend(expr.attrs);
expr.attrs = attrs;
expr
})
})
}
}
fn parse_expr_dot_or_call_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> {
loop { loop {
let has_question = let has_question =
if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) { if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) {
// we are using noexpect here because we don't expect a `?` directly after a `return` // We are using noexpect here because we don't expect a `?` directly after
// which could be suggested otherwise // a `return` which could be suggested otherwise.
self.eat_noexpect(&token::Question) self.eat_noexpect(&token::Question)
} else { } else {
self.eat(&token::Question) self.eat(&token::Question)
@ -921,9 +901,10 @@ impl<'a> Parser<'a> {
e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e)); e = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Try(e));
continue; continue;
} }
let has_dot = if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) { let has_dot =
// we are using noexpect here because we don't expect a `.` directly after a `return` if self.prev_token.kind == TokenKind::Ident(kw::Return, IdentIsRaw::No) {
// which could be suggested otherwise // We are using noexpect here because we don't expect a `.` directly after
// a `return` which could be suggested otherwise.
self.eat_noexpect(&token::Dot) self.eat_noexpect(&token::Dot)
} else if self.token.kind == TokenKind::RArrow && self.may_recover() { } else if self.token.kind == TokenKind::RArrow && self.may_recover() {
// Recovery for `expr->suffix`. // Recovery for `expr->suffix`.
@ -948,6 +929,21 @@ impl<'a> Parser<'a> {
_ => return Ok(e), _ => return Ok(e),
} }
} }
});
// Stitch the list of outer attributes onto the return value. A little
// bit ugly, but the best way given the current code structure.
if attrs.is_empty() {
res
} else {
res.map(|expr| {
expr.map(|mut expr| {
attrs.extend(expr.attrs);
expr.attrs = attrs;
expr
})
})
}
} }
pub(super) fn parse_dot_suffix_expr( pub(super) fn parse_dot_suffix_expr(