From bfb760c697715c5662c4d8330d7e2d0b7910224e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 19 Dec 2013 09:21:05 -0800 Subject: [PATCH] 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 --- src/libsyntax/parse/parser.rs | 9 +++++-- src/test/compile-fail/issue-10392-2.rs | 18 +++++++++++++ src/test/compile-fail/issue-10392.rs | 17 ++++++++++++ src/test/run-pass/issue-10392.rs | 37 ++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/issue-10392-2.rs create mode 100644 src/test/compile-fail/issue-10392.rs create mode 100644 src/test/run-pass/issue-10392.rs 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 or the MIT license +// , 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 or the MIT license +// , 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 or the MIT license +// , 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() } +}