1
Fork 0

refactor parse_field

This commit is contained in:
Mazdak Farrokhzad 2019-12-04 03:23:20 +01:00
parent a916ac22b9
commit e77b9d36ca

View file

@ -1866,48 +1866,51 @@ 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)?;
// Check for an equals token. This means the source incorrectly attempts to let path = ast::Path::from_ident(ident);
// initialize a field with an eq rather than a colon. (ident, self.mk_expr(ident.span, ExprKind::Path(None, path), AttrVec::new()))
if self.token == token::Eq { } else {
self.diagnostic() let ident = self.parse_field_name()?;
.struct_span_err(self.token.span, "expected `:`, found `=`") self.error_on_eq_field_init(ident);
.span_suggestion( self.bump(); // `:`
fieldname.span.shrink_to_hi().to(self.token.span), (ident, self.parse_expr()?)
"replace equals symbol with a colon", };
":".to_string(),
Applicability::MachineApplicable,
)
.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 { Ok(ast::Field {
ident: fieldname, ident,
span: lo.to(expr.span), span: lo.to(expr.span),
expr, expr,
is_shorthand, is_shorthand,
attrs: attrs.into(), attrs,
id: DUMMY_NODE_ID, id: DUMMY_NODE_ID,
is_placeholder: false, 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;
}
self.diagnostic()
.struct_span_err(self.token.span, "expected `:`, found `=`")
.span_suggestion(
field_name.span.shrink_to_hi().to(self.token.span),
"replace equals symbol with a colon",
":".to_string(),
Applicability::MachineApplicable,
)
.emit();
}
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: `...`")
.span_suggestion( .span_suggestion(