Skip to content

Commit 728d16c

Browse files
committed
rustc: Parse new-style impl declarations
1 parent 587b0ed commit 728d16c

File tree

1 file changed

+69
-34
lines changed

1 file changed

+69
-34
lines changed

Diff for: src/libsyntax/parse/parser.rs

+69-34
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)