about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-12-19 09:21:05 -0800
committerAlex Crichton <alex@alexcrichton.com>2013-12-19 09:29:41 -0800
commitbfb760c697715c5662c4d8330d7e2d0b7910224e (patch)
treece0f3e990d3922b766be7d7eaff189118bbf3fe6
parente86cdaf23ded0d25582a33fea761963cf0eb4f41 (diff)
Accept trailing commas in struct patterns
We decided in the 12/10/13 weekly meeting that trailing commas should be
accepted pretty much anywhere. They are currently not allowed in struct
patterns, and this commit adds support for that.

Closes #10392
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/test/compile-fail/issue-10392-2.rs18
-rw-r--r--src/test/compile-fail/issue-10392.rs17
-rw-r--r--src/test/run-pass/issue-10392.rs37
4 files changed, 79 insertions, 2 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 35ea06d62ca..729d0320435 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2800,8 +2800,13 @@ impl Parser {
         let mut etc = false;
         let mut first = true;
         while *self.token != token::RBRACE {
-            if first { first = false; }
-            else { self.expect(&token::COMMA); }
+            if first {
+                first = false;
+            } else {
+                self.expect(&token::COMMA);
+                // accept trailing commas
+                if *self.token == token::RBRACE { break }
+            }
 
             etc = *self.token == token::UNDERSCORE || *self.token == token::DOTDOT;
             if *self.token == token::UNDERSCORE {
diff --git a/src/test/compile-fail/issue-10392-2.rs b/src/test/compile-fail/issue-10392-2.rs
new file mode 100644
index 00000000000..8d7125d7fdd
--- /dev/null
+++ b/src/test/compile-fail/issue-10392-2.rs
@@ -0,0 +1,18 @@
+// Copyright 2012-2013 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.
+
+struct A { foo: int }
+
+fn a() -> A { fail!() }
+
+fn main() {
+    let A { .., } = a(); //~ ERROR: expected `}`
+}
+
diff --git a/src/test/compile-fail/issue-10392.rs b/src/test/compile-fail/issue-10392.rs
new file mode 100644
index 00000000000..455704376d6
--- /dev/null
+++ b/src/test/compile-fail/issue-10392.rs
@@ -0,0 +1,17 @@
+// Copyright 2012-2013 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.
+
+struct A { foo: int }
+
+fn a() -> A { fail!() }
+
+fn main() {
+    let A { , } = a(); //~ ERROR: expected ident
+}
diff --git a/src/test/run-pass/issue-10392.rs b/src/test/run-pass/issue-10392.rs
new file mode 100644
index 00000000000..796fae7dc32
--- /dev/null
+++ b/src/test/run-pass/issue-10392.rs
@@ -0,0 +1,37 @@
+// Copyright 2013 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.
+
+struct A { foo: int }
+struct B { a: int, b: int, c: int }
+
+fn mka() -> A { fail!() }
+fn mkb() -> B { fail!() }
+
+fn test() {
+    let A { foo, } = mka();
+    let A {
+        foo,
+    } = mka();
+
+    let B { a, b, c, } = mkb();
+
+    match mka() {
+        A { foo: _foo, } => {}
+    }
+
+    match Some(mka()) {
+        Some(A { foo: _foo, }) => {}
+        None => {}
+    }
+}
+
+pub fn main() {
+    if false { test() }
+}