@@ -42,14 +42,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
42
42
mac_ellipsis, mac_invoc, mac_invoc_tt, mac_var, matcher,
43
43
match_nonterminal, match_seq, match_tok, method, mode, mt, mul,
44
44
mutability, neg, noreturn, not, pat, pat_box, pat_enum,
45
- pat_ident, pat_lit, pat_range, pat_rec, pat_tup , pat_uniq ,
46
- pat_wild, path, private, proto, proto_bare, proto_block ,
47
- proto_box, proto_uniq, provided, public, pure_fn, purity ,
48
- re_anon, re_named, region, rem, required, ret_style, return_val ,
49
- self_ty, shl, shr, stmt, stmt_decl, stmt_expr, stmt_semi ,
50
- subtract, sty_box, sty_by_ref, sty_region, sty_uniq, sty_value ,
51
- token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok ,
52
- tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
45
+ pat_ident, pat_lit, pat_range, pat_rec, pat_struct , pat_tup ,
46
+ pat_uniq , pat_wild, path, private, proto, proto_bare,
47
+ proto_block , proto_box, proto_uniq, provided, public, pure_fn,
48
+ purity , re_anon, re_named, region, rem, required, ret_style,
49
+ return_val , self_ty, shl, shr, stmt, stmt_decl, stmt_expr,
50
+ stmt_semi , subtract, sty_box, sty_by_ref, sty_region, sty_uniq,
51
+ sty_value , token_tree, trait_method, trait_ref, tt_delim, tt_seq,
52
+ tt_tok , tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn,
53
53
ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_path, ty_ptr,
54
54
ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq, ty_vec,
55
55
ty_fixed_length, unchecked_blk, uniq, unsafe_blk, unsafe_fn,
@@ -1640,6 +1640,52 @@ class parser {
1640
1640
};
1641
1641
}
1642
1642
1643
+ fn parse_pat_fields(refutable: bool) -> (~[ast::field_pat], bool) {
1644
+ let mut fields = ~[];
1645
+ let mut etc = false;
1646
+ let mut first = true;
1647
+ while self.token != token::RBRACE {
1648
+ if first { first = false; }
1649
+ else { self.expect(token::COMMA); }
1650
+
1651
+ if self.token == token::UNDERSCORE {
1652
+ self.bump();
1653
+ if self.token != token::RBRACE {
1654
+ self.fatal(~" expected `} `, found `" +
1655
+ token_to_str ( self . reader , self . token ) +
1656
+ ~"`") ;
1657
+ }
1658
+ etc = true ;
1659
+ break ;
1660
+ }
1661
+
1662
+ let lo1 = self . last_span . lo ;
1663
+ let fieldname = if self . look_ahead ( 1 u) == token:: COLON {
1664
+ self . parse_ident ( )
1665
+ } else {
1666
+ self . parse_value_ident ( )
1667
+ } ;
1668
+ let hi1 = self . last_span . lo ;
1669
+ let fieldpath = ast_util:: ident_to_path ( mk_sp ( lo1, hi1) ,
1670
+ fieldname) ;
1671
+ let mut subpat;
1672
+ if self . token == token:: COLON {
1673
+ self . bump ( ) ;
1674
+ subpat = self . parse_pat ( refutable) ;
1675
+ } else {
1676
+ subpat = @{
1677
+ id: self . get_id ( ) ,
1678
+ node: pat_ident ( bind_by_implicit_ref,
1679
+ fieldpath,
1680
+ none) ,
1681
+ span: self . last_span
1682
+ } ;
1683
+ }
1684
+ vec:: push ( fields, { ident: fieldname, pat: subpat} ) ;
1685
+ }
1686
+ return ( fields, etc) ;
1687
+ }
1688
+
1643
1689
fn parse_pat ( refutable : bool ) -> @pat {
1644
1690
maybe_whole ! { self , nt_pat} ;
1645
1691
@@ -1685,48 +1731,7 @@ class parser {
1685
1731
}
1686
1732
token:: LBRACE => {
1687
1733
self . bump ( ) ;
1688
- let mut fields = ~[];
1689
- let mut etc = false;
1690
- let mut first = true;
1691
- while self.token != token::RBRACE {
1692
- if first { first = false; }
1693
- else { self.expect(token::COMMA); }
1694
-
1695
- if self.token == token::UNDERSCORE {
1696
- self.bump();
1697
- if self.token != token::RBRACE {
1698
- self.fatal(~" expected `} `, found `" +
1699
- token_to_str ( self . reader , self . token ) +
1700
- ~"`") ;
1701
- }
1702
- etc = true ;
1703
- break ;
1704
- }
1705
-
1706
- let lo1 = self . last_span . lo ;
1707
- let fieldname = if self . look_ahead ( 1 u) == token:: COLON {
1708
- self . parse_ident ( )
1709
- } else {
1710
- self . parse_value_ident ( )
1711
- } ;
1712
- let hi1 = self . last_span . lo ;
1713
- let fieldpath = ast_util:: ident_to_path ( mk_sp ( lo1, hi1) ,
1714
- fieldname) ;
1715
- let mut subpat;
1716
- if self . token == token:: COLON {
1717
- self . bump ( ) ;
1718
- subpat = self . parse_pat ( refutable) ;
1719
- } else {
1720
- subpat = @{
1721
- id: self . get_id ( ) ,
1722
- node: pat_ident ( bind_by_implicit_ref,
1723
- fieldpath,
1724
- none) ,
1725
- span: mk_sp ( lo, hi)
1726
- } ;
1727
- }
1728
- vec:: push ( fields, { ident: fieldname, pat: subpat} ) ;
1729
- }
1734
+ let ( fields, etc) = self . parse_pat_fields ( refutable) ;
1730
1735
hi = self . span . hi ;
1731
1736
self . bump ( ) ;
1732
1737
pat = pat_rec ( fields, etc) ;
@@ -1771,21 +1776,82 @@ class parser {
1771
1776
} else if !is_plain_ident ( self . token ) {
1772
1777
pat = self . parse_enum_variant ( refutable) ;
1773
1778
} else {
1774
- // this is a plain identifier, like `x` or `x(...)`
1779
+ let binding_mode;
1780
+ if self . eat_keyword ( ~"copy") {
1781
+ binding_mode = bind_by_value;
1782
+ } else if refutable {
1783
+ // XXX: Should be bind_by_value, but that's not
1784
+ // backward compatible.
1785
+ binding_mode = bind_by_implicit_ref;
1786
+ } else {
1787
+ binding_mode = bind_by_value;
1788
+ }
1789
+
1790
+ let cannot_be_enum_or_struct;
1775
1791
match self . look_ahead ( 1 ) {
1776
- token:: LPAREN | token:: LBRACKET | token:: LT => {
1777
- pat = self . parse_enum_variant ( refutable) ;
1778
- }
1779
- _ => {
1780
- let binding_mode = if refutable {
1781
- // XXX: Should be bind_by_value, but that's not
1782
- // backward compatible.
1783
- bind_by_implicit_ref
1792
+ token:: LPAREN | token:: LBRACKET | token:: LT |
1793
+ token:: LBRACE =>
1794
+ cannot_be_enum_or_struct = false ,
1795
+ _ =>
1796
+ cannot_be_enum_or_struct = true
1797
+ }
1798
+
1799
+ if is_plain_ident ( self . token ) && cannot_be_enum_or_struct {
1800
+ let name = self . parse_value_path ( ) ;
1801
+ let sub;
1802
+ if self . eat ( token:: AT ) {
1803
+ sub = some ( self . parse_pat ( refutable) ) ;
1784
1804
} else {
1785
- bind_by_value
1805
+ sub = none ;
1786
1806
} ;
1787
- pat = self . parse_pat_ident ( refutable, binding_mode) ;
1788
- }
1807
+ pat = pat_ident ( binding_mode, name, sub) ;
1808
+ } else {
1809
+ let enum_path = self . parse_path_with_tps ( true ) ;
1810
+ match self . token {
1811
+ token:: LBRACE => {
1812
+ self . bump ( ) ;
1813
+ let ( fields, etc) =
1814
+ self . parse_pat_fields ( refutable) ;
1815
+ self . bump ( ) ;
1816
+ pat = pat_struct ( enum_path, fields, etc) ;
1817
+ }
1818
+ _ => {
1819
+ let mut args: ~[ @pat] = ~[ ] ;
1820
+ let mut star_pat = false ;
1821
+ match self . token {
1822
+ token:: LPAREN => match self . look_ahead ( 1 u) {
1823
+ token:: BINOP ( token:: STAR ) => {
1824
+ // This is a "top constructor only" pat
1825
+ self . bump ( ) ; self . bump ( ) ;
1826
+ star_pat = true ;
1827
+ self . expect ( token:: RPAREN ) ;
1828
+ }
1829
+ _ => {
1830
+ args = self . parse_unspanned_seq (
1831
+ token:: LPAREN , token:: RPAREN ,
1832
+ seq_sep_trailing_disallowed
1833
+ ( token:: COMMA ) ,
1834
+ |p| p. parse_pat ( refutable) ) ;
1835
+ }
1836
+ }
1837
+ _ => ( )
1838
+ }
1839
+ // at this point, we're not sure whether it's a
1840
+ // enum or a bind
1841
+ if star_pat {
1842
+ pat = pat_enum ( enum_path, none) ;
1843
+ }
1844
+ else if vec:: is_empty ( args) &&
1845
+ vec:: len ( enum_path. idents ) == 1 u {
1846
+ pat = pat_ident ( binding_mode,
1847
+ enum_path,
1848
+ none) ;
1849
+ }
1850
+ else {
1851
+ pat = pat_enum ( enum_path, some ( args) ) ;
1852
+ }
1853
+ }
1854
+ }
1789
1855
}
1790
1856
}
1791
1857
hi = self . span . hi ;
0 commit comments