diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-07-24 16:38:24 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-07-24 16:38:24 -0700 |
| commit | 728d16cfca4d1d12fdabbcc666071810c4d94dc9 (patch) | |
| tree | 613fe2fb692e2d72adf91a641aae1e42bfd67c33 /src/libsyntax/parse | |
| parent | 587b0edbbf6c3ac587be98679c4262049aa2a305 (diff) | |
| download | rust-728d16cfca4d1d12fdabbcc666071810c4d94dc9.tar.gz rust-728d16cfca4d1d12fdabbcc666071810c4d94dc9.zip | |
rustc: Parse new-style impl declarations
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 103 |
1 files changed, 69 insertions, 34 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 0686bad2532..de772b0ff1c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2089,51 +2089,86 @@ class parser { (ident, item_trait(tps, meths), none) } - // Parses three variants (with the region/type params always optional): + // Parses four variants (with the region/type params always optional): // impl /&<T: copy> of to_str for ~[T] { ... } // impl name/&<T> of to_str for ~[T] { ... } // impl name/&<T> for ~[T] { ... } + // impl<T> ~[T] : to_str { ... } fn parse_item_impl() -> item_info { fn wrap_path(p: parser, pt: @path) -> @ty { @{id: p.get_id(), node: ty_path(pt, p.get_id()), span: pt.span} } - let mut (ident, tps) = { - if self.token == token::LT { - (none, self.parse_ty_params()) - } else if self.token == token::BINOP(token::SLASH) { - self.parse_region_param(); - (none, self.parse_ty_params()) + + // We do two separate paths here: old-style impls and new-style impls. + + // First, parse type parameters if necessary. + let mut tps; + if self.token == token::LT { + tps = self.parse_ty_params(); + } else { + tps = ~[]; + } + + let mut ident; + let ty, traits; + if !self.is_keyword(~"of") && + !self.token_is_keyword(~"of", self.look_ahead(1)) && + !self.token_is_keyword(~"for", self.look_ahead(1)) && + self.look_ahead(1) != token::BINOP(token::SLASH) && + self.look_ahead(1) != token::LT { + + // This is a new-style impl declaration. + ident = @~"__extensions__"; // XXX: clownshoes + + // Parse the type. + ty = self.parse_ty(false); + + // Parse traits, if necessary. + if self.token == token::COLON { + self.bump(); + traits = self.parse_trait_ref_list(token::LBRACE); + } else { + traits = ~[]; } - else if self.is_keyword(~"of") { - (none, ~[]) + } else { + let mut ident_old; + if self.token == token::BINOP(token::SLASH) { + self.parse_region_param(); + ident_old = none; + tps = self.parse_ty_params(); + } else if self.is_keyword(~"of") { + ident_old = none; } else { - let id = self.parse_ident(); + ident_old = some(self.parse_ident()); self.parse_region_param(); - (some(id), self.parse_ty_params()) - } - }; - let traits; - if self.eat_keyword(~"of") { - let for_atom = interner::intern(*self.reader.interner(), @~"for"); - traits = self.parse_trait_ref_list(token::IDENT(for_atom, false)); - if traits.len() >= 1 && option::is_none(ident) { - ident = some(vec::last(traits[0].path.idents)); - } - if traits.len() == 0 { - self.fatal(~"BUG: 'of' but no trait"); + tps = self.parse_ty_params(); } - if traits.len() > 1 { - self.fatal(~"BUG: multiple traits"); - } - } else { - traits = ~[]; - }; - let ident = alt ident { - some(name) { name } - none { self.expect_keyword(~"of"); fail; } - }; - self.expect_keyword(~"for"); - let ty = self.parse_ty(false); + + if self.eat_keyword(~"of") { + let for_atom = interner::intern(*self.reader.interner(), + @~"for"); + traits = self.parse_trait_ref_list + (token::IDENT(for_atom, false)); + if traits.len() >= 1 && option::is_none(ident_old) { + ident_old = some(vec::last(traits[0].path.idents)); + } + if traits.len() == 0 { + self.fatal(~"BUG: 'of' but no trait"); + } + if traits.len() > 1 { + self.fatal(~"BUG: multiple traits"); + } + } else { + traits = ~[]; + }; + ident = alt ident_old { + some(name) { name } + none { self.expect_keyword(~"of"); fail; } + }; + self.expect_keyword(~"for"); + ty = self.parse_ty(false); + } + let mut meths = ~[]; self.expect(token::LBRACE); while !self.eat(token::RBRACE) { |
