about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-01-30 05:06:30 -0800
committerbors <bors@rust-lang.org>2014-01-30 05:06:30 -0800
commite3dc5f5bcd5f5c8cd4267fb7533587e0fb663a60 (patch)
treea8d002315f01cc3c7074088e05f024ef589a81f7
parenta6764c28e6c007fcf70dd34a12518fe4d65f9fb8 (diff)
parent2258243ad87e731eba62b7c30a52c612076ba545 (diff)
downloadrust-e3dc5f5bcd5f5c8cd4267fb7533587e0fb663a60.tar.gz
rust-e3dc5f5bcd5f5c8cd4267fb7533587e0fb663a60.zip
auto merge of #11911 : kballard/rust/empty-functional-update, r=pcwalton
Fixes #8972
-rw-r--r--src/libsyntax/parse/parser.rs17
-rw-r--r--src/libsyntax/print/pprust.rs6
-rw-r--r--src/test/run-pass/struct-lit-functional-update-no-fields.rs35
3 files changed, 45 insertions, 13 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b4de4dabfc6..0c81e87c7b8 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1915,25 +1915,19 @@ impl Parser {
                     let mut fields = ~[];
                     let mut base = None;
 
-                    fields.push(self.parse_field());
                     while self.token != token::RBRACE {
-                        self.commit_expr(fields.last().unwrap().expr,
-                                         &[token::COMMA], &[token::RBRACE]);
-
                         if self.eat(&token::DOTDOT) {
                             base = Some(self.parse_expr());
                             break;
                         }
 
-                        if self.token == token::RBRACE {
-                            // Accept an optional trailing comma.
-                            break;
-                        }
                         fields.push(self.parse_field());
+                        self.commit_expr(fields.last().unwrap().expr,
+                                         &[token::COMMA], &[token::RBRACE]);
                     }
 
                     hi = pth.span.hi;
-                    self.commit_expr_expecting(fields.last().unwrap().expr, token::RBRACE);
+                    self.expect(&token::RBRACE);
                     ex = ExprStruct(pth, fields, base);
                     return self.mk_expr(lo, hi, ex);
                 }
@@ -2583,8 +2577,9 @@ impl Parser {
     // For distingishing between struct literals and blocks
     fn looking_at_struct_literal(&mut self) -> bool {
         self.token == token::LBRACE &&
-        (self.look_ahead(1, |t| token::is_plain_ident(t)) &&
-         self.look_ahead(2, |t| *t == token::COLON))
+        ((self.look_ahead(1, |t| token::is_plain_ident(t)) &&
+          self.look_ahead(2, |t| *t == token::COLON))
+         || self.look_ahead(1, |t| *t == token::DOTDOT))
     }
 
     fn parse_match_expr(&mut self) -> @Expr {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 68efdf31e03..019f86b342d 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1174,8 +1174,10 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) {
         match wth {
             Some(expr) => {
                 ibox(s, indent_unit);
-                word(&mut s.s, ",");
-                space(&mut s.s);
+                if !fields.is_empty() {
+                    word(&mut s.s, ",");
+                    space(&mut s.s);
+                }
                 word(&mut s.s, "..");
                 print_expr(s, expr);
                 end(s);
diff --git a/src/test/run-pass/struct-lit-functional-update-no-fields.rs b/src/test/run-pass/struct-lit-functional-update-no-fields.rs
new file mode 100644
index 00000000000..f63a729a5b8
--- /dev/null
+++ b/src/test/run-pass/struct-lit-functional-update-no-fields.rs
@@ -0,0 +1,35 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#[deriving(Eq,Clone)]
+struct Foo<T> {
+    bar: T,
+    baz: T
+}
+
+pub fn main() {
+    let foo = Foo {
+        bar: 0,
+        baz: 1
+    };
+
+    let foo_ = foo.clone();
+    let foo = Foo { ..foo };
+    assert_eq!(foo, foo_);
+
+    let foo = Foo {
+        bar: ~"one",
+        baz: ~"two"
+    };
+
+    let foo_ = foo.clone();
+    let foo = Foo { ..foo };
+    assert_eq!(foo, foo_);
+}