rustc: Parse new-style impl declarations
This commit is contained in:
parent
587b0edbbf
commit
728d16cfca
@ -2089,51 +2089,86 @@ fn parse_item_trait() -> item_info {
|
||||
(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())
|
||||
}
|
||||
else if self.is_keyword(~"of") {
|
||||
(none, ~[])
|
||||
|
||||
// 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 {
|
||||
let id = 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");
|
||||
}
|
||||
if traits.len() > 1 {
|
||||
self.fatal(~"BUG: multiple traits");
|
||||
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);
|
||||
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 {
|
||||
ident_old = some(self.parse_ident());
|
||||
self.parse_region_param();
|
||||
tps = self.parse_ty_params();
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user