item_class(@struct_def, ~[ty_param]),
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
item_impl(~[ty_param],
- ~[@trait_ref], /* traits this impl implements */
+ Option<@trait_ref>, /* (optional) trait this impl implements */
@ty, /* self */
~[@method]),
item_mac(mac),
// Parse traits, if necessary.
- let traits = if self.token == token::COLON {
+ let opt_trait = if self.token == token::COLON {
self.bump();
- self.parse_trait_ref_list(token::LBRACE)
+ Some(self.parse_trait_ref())
} else {
- ~[]
+ None
};
let mut meths = ~[];
let vis = self.parse_visibility();
vec::push(meths, self.parse_method(vis));
}
- (ident, item_impl(tps, traits, ty, meths), None)
+ (ident, item_impl(tps, opt_trait, ty, meths), None)
}
// Instantiates ident <i> with references to <typarams> as arguments.
print_struct(s, struct_def, tps, item.ident, item.span);
}
- ast::item_impl(tps, traits, ty, methods) => {
+ ast::item_impl(tps, opt_trait, ty, methods) => {
head(s, ~"impl");
if tps.is_not_empty() {
print_type_params(s, tps);
}
print_type(s, ty);
- if vec::len(traits) != 0u {
- word_space(s, ~":");
- do commasep(s, inconsistent, traits) |s, p| {
- print_path(s, p.path, false);
+ match opt_trait {
+ Some(t) => {
+ word_space(s, ~":");
+ print_path(s, t.path, false);
}
- }
+ None => ()
+ };
space(s.s);
bopen(s);
else { None }, tps);
}
}
- item_impl(tps, traits, _, methods) => {
+ item_impl(tps, opt_trait, _, methods) => {
add_to_index();
ebml_w.start_tag(tag_items_data_item);
encode_def_id(ebml_w, local_def(item.id));
ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
ebml_w.end_tag();
}
- if traits.len() > 1 {
- fail ~"multiple traits!!";
- }
- for traits.each |associated_trait| {
+ do opt_trait.iter() |associated_trait| {
encode_trait_ref(ebml_w, ecx, associated_trait)
}
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
fn resolve_implementation(id: node_id,
span: span,
type_parameters: ~[ty_param],
- trait_references: ~[@trait_ref],
+ opt_trait_reference: Option<@trait_ref>,
self_type: @ty,
methods: ~[@method],
visitor: ResolveVisitor) {
// Resolve the trait reference, if necessary.
let original_trait_refs = self.current_trait_refs;
- if trait_references.len() >= 1 {
- let mut new_trait_refs = @DVec();
- for trait_references.each |trait_reference| {
- match self.resolve_path(
+ match opt_trait_reference {
+ Some(trait_reference) => {
+ let new_trait_refs = @DVec();
+ match self.resolve_path(
trait_reference.path, TypeNS, true, visitor) {
None => {
self.session.span_err(span,
(*new_trait_refs).push(def_id_of_def(def));
}
}
- }
-
// Record the current set of trait references.
self.current_trait_refs = Some(new_trait_refs);
}
+ None => ()
+ }
// Resolve the self type.
self.resolve_type(self_type, visitor);
debug!("(impl_traits) searching for trait impl %?", id);
match cx.items.find(id.node) {
Some(ast_map::node_item(@{
- node: ast::item_impl(_, trait_refs, _, _),
+ node: ast::item_impl(_, opt_trait, _, _),
_},
_)) => {
- do vec::map(trait_refs) |trait_ref| {
- node_id_to_type(cx, trait_ref.ref_id)
- }
+ do option::map_default(opt_trait, ~[]) |trait_ref| {
+ ~[node_id_to_type(cx, trait_ref.ref_id)]
+ }
}
Some(ast_map::node_item(@{node: ast::item_class(sd,_),
_},_)) => {
self.crate_context.tcx.sess.str_of(item.ident));
match item.node {
- item_impl(_, associated_traits, _, _) => {
- self.check_implementation(item, associated_traits);
+ item_impl(_, opt_trait, _, _) => {
+ self.check_implementation(item, opt_trait.to_vec());
}
item_class(struct_def, _) => {
self.check_implementation(item, struct_def.traits);
// Then visit the module items.
visit_mod(module_, item.span, item.id, (), visitor);
}
- item_impl(_, associated_traits, _, _) => {
+ item_impl(_, opt_trait, _, _) => {
match self.base_type_def_ids.find(
local_def(item.id)) {
// if the traits are defined in the same
// crate.
- if associated_traits.len() == 0 {
+ match opt_trait {
+ None => {
// There is no trait to implement, so
// this is an error.
or new type \
instead");
}
+ _ => ()
+ }
- for associated_traits.each |trait_ref| {
+ do opt_trait.iter() |trait_ref| {
// This is OK if and only if the
// trait was defined in this
// crate.
let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| {
match ctxt.ast_map.get(doc.id()) {
ast_map::node_item(@{
- node: ast::item_impl(_, trait_types, self_ty, _), _
+ node: ast::item_impl(_, opt_trait_type, self_ty, _), _
}, _) => {
- let trait_types = vec::map(trait_types, |p| {
- pprust::path_to_str(p.path, extract::interner())
+ let trait_types = opt_trait_type.map_default(~[], |p| {
+ ~[pprust::path_to_str(p.path, extract::interner())]
});
(trait_types, Some(pprust::ty_to_str(self_ty,
extract::interner())))
--- /dev/null
+struct S {
+ y: int;
+}
+
+impl S: Cmp, ToStr { //~ ERROR: expected `{` but found `,`
+ fn eq(&&other: S) { false }
+ fn to_str() -> ~str { ~"hi" }
+}
\ No newline at end of file