diff options
| author | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-04-20 00:54:42 -0700 |
|---|---|---|
| committer | Tim Chevalier <chevalier@alum.wellesley.edu> | 2012-04-20 00:56:46 -0700 |
| commit | 37b054973083ed4201a2ba73be6bdd39daf13cf6 (patch) | |
| tree | 842be52963bf339cb1eead62d0fc5935ba22f90f /src/librustsyntax/parse/parser.rs | |
| parent | 087b12ac297ac9462013b01ccc69097bdf92900c (diff) | |
| download | rust-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.rs | 32 |
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)); } } } |
