mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Rollup merge of #122858 - nnethercote:tweak-parse_dot_suffix_expr, r=est31
Tweak `parse_dot_suffix_expr` I find this function hard to understand, so I rewrote it. r? ```@est31```
This commit is contained in:
commit
4cae68b0cf
@ -16,7 +16,6 @@ use core::mem;
|
|||||||
use core::ops::ControlFlow;
|
use core::ops::ControlFlow;
|
||||||
use rustc_ast::ptr::P;
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||||
use rustc_ast::tokenstream::Spacing;
|
|
||||||
use rustc_ast::util::case::Case;
|
use rustc_ast::util::case::Case;
|
||||||
use rustc_ast::util::classify;
|
use rustc_ast::util::classify;
|
||||||
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
|
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
|
||||||
@ -999,13 +998,57 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
|
pub fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> {
|
||||||
|
// At this point we've consumed something like `expr.` and `self.token` holds the token
|
||||||
|
// after the dot.
|
||||||
match self.token.uninterpolate().kind {
|
match self.token.uninterpolate().kind {
|
||||||
token::Ident(..) => self.parse_dot_suffix(base, lo),
|
token::Ident(..) => self.parse_dot_suffix(base, lo),
|
||||||
token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
|
token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => {
|
||||||
Ok(self.parse_expr_tuple_field_access(lo, base, symbol, suffix, None))
|
let ident_span = self.token.span;
|
||||||
|
self.bump();
|
||||||
|
Ok(self.mk_expr_tuple_field_access(lo, ident_span, base, symbol, suffix))
|
||||||
}
|
}
|
||||||
token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => {
|
token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => {
|
||||||
Ok(self.parse_expr_tuple_field_access_float(lo, base, symbol, suffix))
|
Ok(match self.break_up_float(symbol, self.token.span) {
|
||||||
|
// 1e2
|
||||||
|
DestructuredFloat::Single(sym, _sp) => {
|
||||||
|
// `foo.1e2`: a single complete dot access, fully consumed. We end up with
|
||||||
|
// the `1e2` token in `self.prev_token` and the following token in
|
||||||
|
// `self.token`.
|
||||||
|
let ident_span = self.token.span;
|
||||||
|
self.bump();
|
||||||
|
self.mk_expr_tuple_field_access(lo, ident_span, base, sym, suffix)
|
||||||
|
}
|
||||||
|
// 1.
|
||||||
|
DestructuredFloat::TrailingDot(sym, ident_span, dot_span) => {
|
||||||
|
// `foo.1.`: a single complete dot access and the start of another.
|
||||||
|
// We end up with the `sym` (`1`) token in `self.prev_token` and a dot in
|
||||||
|
// `self.token`.
|
||||||
|
assert!(suffix.is_none());
|
||||||
|
self.token = Token::new(token::Ident(sym, IdentIsRaw::No), ident_span);
|
||||||
|
self.bump_with((Token::new(token::Dot, dot_span), self.token_spacing));
|
||||||
|
self.mk_expr_tuple_field_access(lo, ident_span, base, sym, None)
|
||||||
|
}
|
||||||
|
// 1.2 | 1.2e3
|
||||||
|
DestructuredFloat::MiddleDot(
|
||||||
|
sym1,
|
||||||
|
ident1_span,
|
||||||
|
_dot_span,
|
||||||
|
sym2,
|
||||||
|
ident2_span,
|
||||||
|
) => {
|
||||||
|
// `foo.1.2` (or `foo.1.2e3`): two complete dot accesses. We end up with
|
||||||
|
// the `sym2` (`2` or `2e3`) token in `self.prev_token` and the following
|
||||||
|
// token in `self.token`.
|
||||||
|
let next_token2 =
|
||||||
|
Token::new(token::Ident(sym2, IdentIsRaw::No), ident2_span);
|
||||||
|
self.bump_with((next_token2, self.token_spacing));
|
||||||
|
self.bump();
|
||||||
|
let base1 =
|
||||||
|
self.mk_expr_tuple_field_access(lo, ident1_span, base, sym1, None);
|
||||||
|
self.mk_expr_tuple_field_access(lo, ident2_span, base1, sym2, suffix)
|
||||||
|
}
|
||||||
|
DestructuredFloat::Error => base,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.error_unexpected_after_dot();
|
self.error_unexpected_after_dot();
|
||||||
@ -1119,41 +1162,6 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expr_tuple_field_access_float(
|
|
||||||
&mut self,
|
|
||||||
lo: Span,
|
|
||||||
base: P<Expr>,
|
|
||||||
float: Symbol,
|
|
||||||
suffix: Option<Symbol>,
|
|
||||||
) -> P<Expr> {
|
|
||||||
match self.break_up_float(float, self.token.span) {
|
|
||||||
// 1e2
|
|
||||||
DestructuredFloat::Single(sym, _sp) => {
|
|
||||||
self.parse_expr_tuple_field_access(lo, base, sym, suffix, None)
|
|
||||||
}
|
|
||||||
// 1.
|
|
||||||
DestructuredFloat::TrailingDot(sym, ident_span, dot_span) => {
|
|
||||||
assert!(suffix.is_none());
|
|
||||||
self.token = Token::new(token::Ident(sym, IdentIsRaw::No), ident_span);
|
|
||||||
let next_token = (Token::new(token::Dot, dot_span), self.token_spacing);
|
|
||||||
self.parse_expr_tuple_field_access(lo, base, sym, None, Some(next_token))
|
|
||||||
}
|
|
||||||
// 1.2 | 1.2e3
|
|
||||||
DestructuredFloat::MiddleDot(symbol1, ident1_span, dot_span, symbol2, ident2_span) => {
|
|
||||||
self.token = Token::new(token::Ident(symbol1, IdentIsRaw::No), ident1_span);
|
|
||||||
// This needs to be `Spacing::Alone` to prevent regressions.
|
|
||||||
// See issue #76399 and PR #76285 for more details
|
|
||||||
let next_token1 = (Token::new(token::Dot, dot_span), Spacing::Alone);
|
|
||||||
let base1 =
|
|
||||||
self.parse_expr_tuple_field_access(lo, base, symbol1, None, Some(next_token1));
|
|
||||||
let next_token2 = Token::new(token::Ident(symbol2, IdentIsRaw::No), ident2_span);
|
|
||||||
self.bump_with((next_token2, self.token_spacing)); // `.`
|
|
||||||
self.parse_expr_tuple_field_access(lo, base1, symbol2, suffix, None)
|
|
||||||
}
|
|
||||||
DestructuredFloat::Error => base,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse the field access used in offset_of, matched by `$(e:expr)+`.
|
/// Parse the field access used in offset_of, matched by `$(e:expr)+`.
|
||||||
/// Currently returns a list of idents. However, it should be possible in
|
/// Currently returns a list of idents. However, it should be possible in
|
||||||
/// future to also do array indices, which might be arbitrary expressions.
|
/// future to also do array indices, which might be arbitrary expressions.
|
||||||
@ -1255,24 +1263,18 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(fields.into_iter().collect())
|
Ok(fields.into_iter().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_expr_tuple_field_access(
|
fn mk_expr_tuple_field_access(
|
||||||
&mut self,
|
&mut self,
|
||||||
lo: Span,
|
lo: Span,
|
||||||
|
ident_span: Span,
|
||||||
base: P<Expr>,
|
base: P<Expr>,
|
||||||
field: Symbol,
|
field: Symbol,
|
||||||
suffix: Option<Symbol>,
|
suffix: Option<Symbol>,
|
||||||
next_token: Option<(Token, Spacing)>,
|
|
||||||
) -> P<Expr> {
|
) -> P<Expr> {
|
||||||
match next_token {
|
|
||||||
Some(next_token) => self.bump_with(next_token),
|
|
||||||
None => self.bump(),
|
|
||||||
}
|
|
||||||
let span = self.prev_token.span;
|
|
||||||
let field = ExprKind::Field(base, Ident::new(field, span));
|
|
||||||
if let Some(suffix) = suffix {
|
if let Some(suffix) = suffix {
|
||||||
self.expect_no_tuple_index_suffix(span, suffix);
|
self.expect_no_tuple_index_suffix(ident_span, suffix);
|
||||||
}
|
}
|
||||||
self.mk_expr(lo.to(span), field)
|
self.mk_expr(lo.to(ident_span), ExprKind::Field(base, Ident::new(field, ident_span)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a function call expression, `expr(...)`.
|
/// Parse a function call expression, `expr(...)`.
|
||||||
|
Loading…
Reference in New Issue
Block a user