about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-10-26 21:47:25 -0700
committerGitHub <noreply@github.com>2016-10-26 21:47:25 -0700
commitbc283c9487b4607d0a97635dca8c8812b886047b (patch)
tree040a1ecd30c067e722c03ff8a05dc1de0dfb2c29 /src/libsyntax/parse
parent4a584637b0081c96c53c6048fd3715912c94a59b (diff)
parent9908711e5e985e322a9576b25f982835504ead5c (diff)
downloadrust-bc283c9487b4607d0a97635dca8c8812b886047b.tar.gz
rust-bc283c9487b4607d0a97635dca8c8812b886047b.zip
Auto merge of #11994 - eddyb:struct-literal-field-shorthand, r=nrc
Implement field shorthands in struct literal expressions.

Implements #37340 in a straight-forward way: `Foo { x, y: f() }` parses as `Foo { x: x, y: f() }`.
Because of the added `is_shorthand` to `ast::Field`, this is `[syntax-breaking]` (cc @Manishearth).

* [x] Mark the fields as being a shorthand (the exact same way we do it in patterns), for pretty-printing.
* [x] Gate the shorthand syntax with `#![feature(field_init_shorthand)]`.
* [x] Don't parse numeric field as identifiers.
* [x] Arbitrary field order tests.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 463ec334cc5..a5a081e08be 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2007,17 +2007,30 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse ident COLON expr
+    /// Parse ident (COLON expr)?
     pub fn parse_field(&mut self) -> PResult<'a, Field> {
         let lo = self.span.lo;
-        let i = self.parse_field_name()?;
-        let hi = self.prev_span.hi;
-        self.expect(&token::Colon)?;
-        let e = self.parse_expr()?;
+        let hi;
+
+        // Check if a colon exists one ahead. This means we're parsing a fieldname.
+        let (fieldname, expr, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
+            let fieldname = self.parse_field_name()?;
+            self.bump();
+            hi = self.prev_span.hi;
+            (fieldname, self.parse_expr()?, false)
+        } else {
+            let fieldname = self.parse_ident()?;
+            hi = self.prev_span.hi;
+
+            // Mimic `x: x` for the `x` field shorthand.
+            let path = ast::Path::from_ident(mk_sp(lo, hi), fieldname);
+            (fieldname, self.mk_expr(lo, hi, ExprKind::Path(None, path), ThinVec::new()), true)
+        };
         Ok(ast::Field {
-            ident: spanned(lo, hi, i),
-            span: mk_sp(lo, e.span.hi),
-            expr: e,
+            ident: spanned(lo, hi, fieldname),
+            span: mk_sp(lo, expr.span.hi),
+            expr: expr,
+            is_shorthand: is_shorthand,
         })
     }