about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-02-19 09:14:33 -0800
committerbors <bors@rust-lang.org>2013-02-19 09:14:33 -0800
commitf68335113bf277f171494abb62a31293311f80c8 (patch)
treea790a66032447ff99658c7fe4525881c182170f6 /src/libsyntax/parse
parent2ec958db5ae37f193d4d632635818241b134a617 (diff)
parentaa284de1fc246b55fb53783ded3e9786e04b03d0 (diff)
downloadrust-f68335113bf277f171494abb62a31293311f80c8.tar.gz
rust-f68335113bf277f171494abb62a31293311f80c8.zip
auto merge of #5002 : catamorphism/rust/one-tuples, r=graydon
r? @graydon - This is for greater uniformity (for example, macros that generate
tuples). rustc already supported 1-tuple patterns, but there was no
way to construct a 1-tuple term.

@graydon , as far as your comment on #4898 - it did turn out to be solvable inside the macro (since @luqmana already fixed it using structs instead), but I still think it's a good idea to allow 1-tuples, for uniformity. I don't think anyone is likely to trip over it, and I'm not too worried that it changes the amount of ambiguity.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fa51d4c29d2..e5b3024d3dc 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -576,12 +576,21 @@ pub impl Parser {
                 self.bump();
                 ty_nil
             } else {
+                // (t) is a parenthesized ty
+                // (t,) is the type of a tuple with only one field,
+                // of type t
                 let mut ts = ~[self.parse_ty(false)];
+                let mut one_tuple = false;
                 while self.token == token::COMMA {
                     self.bump();
-                    ts.push(self.parse_ty(false));
+                    if self.token != token::RPAREN {
+                        ts.push(self.parse_ty(false));
+                    }
+                    else {
+                        one_tuple = true;
+                    }
                 }
-                let t = if vec::len(ts) == 1u { ts[0].node }
+                let t = if ts.len() == 1 && !one_tuple { ts[0].node }
                 else { ty_tup(ts) };
                 self.expect(token::RPAREN);
                 t
@@ -1061,6 +1070,9 @@ pub impl Parser {
 
         if self.token == token::LPAREN {
             self.bump();
+            // (e) is parenthesized e
+            // (e,) is a tuple with only one field, e
+            let mut one_tuple = false;
             if self.token == token::RPAREN {
                 hi = self.span.hi;
                 self.bump();
@@ -1069,12 +1081,18 @@ pub impl Parser {
             }
             let mut es = ~[self.parse_expr()];
             while self.token == token::COMMA {
-                self.bump(); es.push(self.parse_expr());
+                self.bump();
+                if self.token != token::RPAREN {
+                    es.push(self.parse_expr());
+                }
+                else {
+                    one_tuple = true;
+                }
             }
             hi = self.span.hi;
             self.expect(token::RPAREN);
 
-            return if es.len() == 1 {
+            return if es.len() == 1 && !one_tuple {
                 self.mk_expr(lo, self.span.hi, expr_paren(es[0]))
             }
             else {
@@ -2158,11 +2176,13 @@ pub impl Parser {
                 pat = pat_lit(expr);
             } else {
                 let mut fields = ~[self.parse_pat(refutable)];
-                while self.token == token::COMMA {
-                    self.bump();
-                    fields.push(self.parse_pat(refutable));
+                if self.look_ahead(1) != token::RPAREN {
+                    while self.token == token::COMMA {
+                        self.bump();
+                        fields.push(self.parse_pat(refutable));
+                    }
                 }
-                if vec::len(fields) == 1u { self.expect(token::COMMA); }
+                if fields.len() == 1 { self.expect(token::COMMA); }
                 hi = self.span.hi;
                 self.expect(token::RPAREN);
                 pat = pat_tup(fields);