@@ -2089,51 +2089,86 @@ class parser {
2089
2089
(ident, item_trait(tps, meths), none)
2090
2090
}
2091
2091
2092
- // Parses three variants (with the region/type params always optional):
2092
+ // Parses four variants (with the region/type params always optional):
2093
2093
// impl /&<T: copy> of to_str for ~[T] { ... }
2094
2094
// impl name/&<T> of to_str for ~[T] { ... }
2095
2095
// impl name/&<T> for ~[T] { ... }
2096
+ // impl<T> ~[T] : to_str { ... }
2096
2097
fn parse_item_impl() -> item_info {
2097
2098
fn wrap_path(p: parser, pt: @path) -> @ty {
2098
2099
@{id: p.get_id(), node: ty_path(pt, p.get_id()), span: pt.span}
2099
2100
}
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 = ~[ ] ;
2106
2132
}
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;
2109
2141
} else {
2110
- let id = self . parse_ident ( ) ;
2142
+ ident_old = some ( self . parse_ident ( ) ) ;
2111
2143
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 ( ) ;
2124
2145
}
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
+
2137
2172
let mut meths = ~[];
2138
2173
self.expect(token::LBRACE);
2139
2174
while !self.eat(token::RBRACE) {
0 commit comments