about summary refs log tree commit diff
path: root/src/librustsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2012-04-20 00:54:42 -0700
committerTim Chevalier <chevalier@alum.wellesley.edu>2012-04-20 00:56:46 -0700
commit37b054973083ed4201a2ba73be6bdd39daf13cf6 (patch)
tree842be52963bf339cb1eead62d0fc5935ba22f90f /src/librustsyntax/parse/parser.rs
parent087b12ac297ac9462013b01ccc69097bdf92900c (diff)
downloadrust-37b054973083ed4201a2ba73be6bdd39daf13cf6.tar.gz
rust-37b054973083ed4201a2ba73be6bdd39daf13cf6.zip
Add new syntax for patterns that match the head constructor only
Adds a new kind of pattern C(*) where C is a constructor that may
have any number of fields. This pattern matches any value
constructed with C, without binding names for any of the fields.

Closes #1701.
Diffstat (limited to 'src/librustsyntax/parse/parser.rs')
-rw-r--r--src/librustsyntax/parse/parser.rs32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs
index 8340fa2f6e7..4131d3eca96 100644
--- a/src/librustsyntax/parse/parser.rs
+++ b/src/librustsyntax/parse/parser.rs
@@ -1417,24 +1417,38 @@ fn parse_pat(p: parser) -> @ast::pat {
         } else {
             let enum_path = parse_path_and_ty_param_substs(p, true);
             hi = enum_path.span.hi;
-            let mut args: [@ast::pat];
+            let mut args: [@ast::pat] = [];
+            let mut star_pat = false;
             alt p.token {
               token::LPAREN {
-                let a =
-                    parse_seq(token::LPAREN, token::RPAREN,
-                              seq_sep(token::COMMA), parse_pat, p);
-                args = a.node;
-                hi = a.span.hi;
+                alt p.look_ahead(1u) {
+                  token::BINOP(token::STAR) {
+                    // This is a "top constructor only" pat
+                    p.bump(); p.bump();
+                    star_pat = true;
+                    expect(p, token::RPAREN);
+                  }
+                  _ {
+                   let a =
+                       parse_seq(token::LPAREN, token::RPAREN,
+                                seq_sep(token::COMMA), parse_pat, p);
+                    args = a.node;
+                    hi = a.span.hi;
+                  }
+                }
               }
-              _ { args = []; }
+              _ { }
             }
             // at this point, we're not sure whether it's a enum or a bind
-            if vec::len(args) == 0u &&
+            if star_pat {
+                 pat = ast::pat_enum(enum_path, none);
+            }
+            else if vec::is_empty(args) &&
                vec::len(enum_path.node.idents) == 1u {
                 pat = ast::pat_ident(enum_path, none);
             }
             else {
-                pat = ast::pat_enum(enum_path, args);
+                pat = ast::pat_enum(enum_path, some(args));
             }
         }
       }