refactor parse_field
This commit is contained in:
parent
a916ac22b9
commit
e77b9d36ca
1 changed files with 33 additions and 30 deletions
|
@ -1866,47 +1866,50 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
/// Parses `ident (COLON expr)?`.
|
/// Parses `ident (COLON expr)?`.
|
||||||
fn parse_field(&mut self) -> PResult<'a, Field> {
|
fn parse_field(&mut self) -> PResult<'a, Field> {
|
||||||
let attrs = self.parse_outer_attributes()?;
|
let attrs = self.parse_outer_attributes()?.into();
|
||||||
let lo = self.token.span;
|
let lo = self.token.span;
|
||||||
|
|
||||||
// Check if a colon exists one ahead. This means we're parsing a fieldname.
|
// Check if a colon exists one ahead. This means we're parsing a fieldname.
|
||||||
let (fieldname, expr, is_shorthand) =
|
let is_shorthand = !self.look_ahead(1, |t| t == &token::Colon || t == &token::Eq);
|
||||||
if self.look_ahead(1, |t| t == &token::Colon || t == &token::Eq) {
|
let (ident, expr) = if is_shorthand {
|
||||||
let fieldname = self.parse_field_name()?;
|
// Mimic `x: x` for the `x` field shorthand.
|
||||||
|
let ident = self.parse_ident_common(false)?;
|
||||||
|
let path = ast::Path::from_ident(ident);
|
||||||
|
(ident, self.mk_expr(ident.span, ExprKind::Path(None, path), AttrVec::new()))
|
||||||
|
} else {
|
||||||
|
let ident = self.parse_field_name()?;
|
||||||
|
self.error_on_eq_field_init(ident);
|
||||||
|
self.bump(); // `:`
|
||||||
|
(ident, self.parse_expr()?)
|
||||||
|
};
|
||||||
|
Ok(ast::Field {
|
||||||
|
ident,
|
||||||
|
span: lo.to(expr.span),
|
||||||
|
expr,
|
||||||
|
is_shorthand,
|
||||||
|
attrs,
|
||||||
|
id: DUMMY_NODE_ID,
|
||||||
|
is_placeholder: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check for `=`. This means the source incorrectly attempts to
|
||||||
|
/// initialize a field with an eq rather than a colon.
|
||||||
|
fn error_on_eq_field_init(&self, field_name: Ident) {
|
||||||
|
if self.token != token::Eq {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for an equals token. This means the source incorrectly attempts to
|
|
||||||
// initialize a field with an eq rather than a colon.
|
|
||||||
if self.token == token::Eq {
|
|
||||||
self.diagnostic()
|
self.diagnostic()
|
||||||
.struct_span_err(self.token.span, "expected `:`, found `=`")
|
.struct_span_err(self.token.span, "expected `:`, found `=`")
|
||||||
.span_suggestion(
|
.span_suggestion(
|
||||||
fieldname.span.shrink_to_hi().to(self.token.span),
|
field_name.span.shrink_to_hi().to(self.token.span),
|
||||||
"replace equals symbol with a colon",
|
"replace equals symbol with a colon",
|
||||||
":".to_string(),
|
":".to_string(),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
self.bump(); // `:`
|
|
||||||
(fieldname, self.parse_expr()?, false)
|
|
||||||
} else {
|
|
||||||
let fieldname = self.parse_ident_common(false)?;
|
|
||||||
|
|
||||||
// Mimic `x: x` for the `x` field shorthand.
|
|
||||||
let path = ast::Path::from_ident(fieldname);
|
|
||||||
let expr = self.mk_expr(fieldname.span, ExprKind::Path(None, path), AttrVec::new());
|
|
||||||
(fieldname, expr, true)
|
|
||||||
};
|
|
||||||
Ok(ast::Field {
|
|
||||||
ident: fieldname,
|
|
||||||
span: lo.to(expr.span),
|
|
||||||
expr,
|
|
||||||
is_shorthand,
|
|
||||||
attrs: attrs.into(),
|
|
||||||
id: DUMMY_NODE_ID,
|
|
||||||
is_placeholder: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn err_dotdotdot_syntax(&self, span: Span) {
|
fn err_dotdotdot_syntax(&self, span: Span) {
|
||||||
self.struct_span_err(span, "unexpected token: `...`")
|
self.struct_span_err(span, "unexpected token: `...`")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue