@@ -2089,51 +2089,86 @@ class parser {
20892089 (ident, item_trait(tps, meths), none)
20902090 }
20912091
2092- // Parses three variants (with the region/type params always optional):
2092+ // Parses four variants (with the region/type params always optional):
20932093 // impl /&<T: copy> of to_str for ~[T] { ... }
20942094 // impl name/&<T> of to_str for ~[T] { ... }
20952095 // impl name/&<T> for ~[T] { ... }
2096+ // impl<T> ~[T] : to_str { ... }
20962097 fn parse_item_impl() -> item_info {
20972098 fn wrap_path(p: parser, pt: @path) -> @ty {
20982099 @{id: p.get_id(), node: ty_path(pt, p.get_id()), span: pt.span}
20992100 }
2100- let mut (ident, tps) = {
2101- if self.token == token::LT {
2102- (none, self.parse_ty_params())
2103- } else if self.token == token::BINOP(token::SLASH) {
2104- self.parse_region_param();
2105- (none, self.parse_ty_params())
2101+
2102+ // We do two separate paths here: old-style impls and new-style impls.
2103+
2104+ // First, parse type parameters if necessary.
2105+ let mut tps;
2106+ if self.token == token::LT {
2107+ tps = self.parse_ty_params();
2108+ } else {
2109+ tps = ~[];
2110+ }
2111+
2112+ let mut ident;
2113+ let ty, traits;
2114+ if !self.is_keyword(~" of") &&
2115+ !self . token_is_keyword ( ~"of", self . look_ahead ( 1 ) ) &&
2116+ !self . token_is_keyword ( ~"for ", self.look_ahead(1)) &&
2117+ self.look_ahead(1) != token::BINOP(token::SLASH) &&
2118+ self.look_ahead(1) != token::LT {
2119+
2120+ // This is a new-style impl declaration.
2121+ ident = @~" __extensions__"; // XXX: clownshoes
2122+
2123+ // Parse the type.
2124+ ty = self . parse_ty ( false ) ;
2125+
2126+ // Parse traits, if necessary.
2127+ if self . token == token:: COLON {
2128+ self . bump ( ) ;
2129+ traits = self . parse_trait_ref_list ( token:: LBRACE ) ;
2130+ } else {
2131+ traits = ~[ ] ;
21062132 }
2107- else if self.is_keyword(~" of") {
2108- ( none, ~[ ] )
2133+ } else {
2134+ let mut ident_old;
2135+ if self . token == token:: BINOP ( token:: SLASH ) {
2136+ self . parse_region_param ( ) ;
2137+ ident_old = none;
2138+ tps = self . parse_ty_params ( ) ;
2139+ } else if self . is_keyword ( ~"of") {
2140+ ident_old = none;
21092141 } else {
2110- let id = self . parse_ident ( ) ;
2142+ ident_old = some ( self . parse_ident ( ) ) ;
21112143 self . parse_region_param ( ) ;
2112- ( some ( id) , self . parse_ty_params ( ) )
2113- }
2114- } ;
2115- let traits;
2116- if self . eat_keyword ( ~"of") {
2117- let for_atom = interner:: intern ( * self . reader . interner ( ) , @~"for ");
2118- traits = self.parse_trait_ref_list(token::IDENT(for_atom, false));
2119- if traits.len() >= 1 && option::is_none(ident) {
2120- ident = some(vec::last(traits[0].path.idents));
2121- }
2122- if traits.len() == 0 {
2123- self.fatal(~" BUG : ' of' but no trait ") ;
2144+ tps = self . parse_ty_params ( ) ;
21242145 }
2125- if traits. len ( ) > 1 {
2126- self . fatal ( ~"BUG : multiple traits") ;
2127- }
2128- } else {
2129- traits = ~[ ] ;
2130- } ;
2131- let ident = alt ident {
2132- some( name) { name }
2133- none { self. expect_keyword ( ~"of") ; fail; }
2134- } ;
2135- self . expect_keyword ( ~"for ");
2136- let ty = self.parse_ty(false);
2146+
2147+ if self . eat_keyword ( ~"of") {
2148+ let for_atom = interner:: intern ( * self . reader . interner ( ) ,
2149+ @~"for ");
2150+ traits = self.parse_trait_ref_list
2151+ (token::IDENT(for_atom, false));
2152+ if traits.len() >= 1 && option::is_none(ident_old) {
2153+ ident_old = some(vec::last(traits[0].path.idents));
2154+ }
2155+ if traits.len() == 0 {
2156+ self.fatal(~" BUG : ' of' but no trait ") ;
2157+ }
2158+ if traits. len ( ) > 1 {
2159+ self . fatal ( ~"BUG : multiple traits") ;
2160+ }
2161+ } else {
2162+ traits = ~[ ] ;
2163+ } ;
2164+ ident = alt ident_old {
2165+ some( name) { name }
2166+ none { self. expect_keyword ( ~"of") ; fail; }
2167+ } ;
2168+ self . expect_keyword ( ~"for ");
2169+ ty = self.parse_ty(false);
2170+ }
2171+
21372172 let mut meths = ~[];
21382173 self.expect(token::LBRACE);
21392174 while !self.eat(token::RBRACE) {
0 commit comments