syntax: Parse multiple trait refs in a single implementation

This commit is contained in:
Patrick Walton 2012-07-18 09:31:53 -07:00
parent 1528256fdc
commit 3ac5b4a86f
14 changed files with 126 additions and 63 deletions

View file

@ -2966,16 +2966,20 @@ class Resolver {
}
}
item_impl(type_parameters, interface_reference, self_type,
item_impl(type_parameters, implemented_traits, self_type,
methods) {
self.resolve_implementation(item.id,
item.span,
type_parameters,
interface_reference,
self_type,
methods,
visitor);
// XXX: Should take an array of traits.
let trait_reference;
if implemented_traits.len() == 0 {
trait_reference = none;
} else {
trait_reference = some(implemented_traits[0]);
}
self.resolve_implementation(item.id, item.span,
type_parameters, trait_reference,
self_type, methods, visitor);
}
item_trait(type_parameters, methods) {

View file

@ -2474,13 +2474,16 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
result
}
// XXX: Needs to return an array of traits.
fn impl_trait(cx: ctxt, id: ast::def_id) -> option<t> {
if id.crate == ast::local_crate {
#debug("(impl_trait) searching for trait impl %?", id);
alt cx.items.find(id.node) {
some(ast_map::node_item(@{node: ast::item_impl(
_, some(@{ref_id: id, _}), _, _), _}, _)) {
some(node_id_to_type(cx, id))
some(ast_map::node_item(@{
node: ast::item_impl(_, traits, _, _),
_},
_)) if traits.len() >= 1 {
some(node_id_to_type(cx, traits[0].ref_id))
}
some(ast_map::node_item(@{node: ast::item_class(*),
_},_)) {

View file

@ -454,7 +454,7 @@ class lookup {
for (*trait_ids).each |trait_id| {
#debug("(adding inherent and extension candidates) \
trying trait: %s",
node_id_to_str(self.tcx().items, trait_id.node));
self.def_id_to_str(trait_id));
let coherence_info = self.fcx.ccx.coherence_info;
alt coherence_info.extension_methods.find(trait_id) {
@ -463,6 +463,10 @@ class lookup {
}
some(extension_methods) {
for extension_methods.each |implementation| {
#debug("(adding inherent and extension \
candidates) adding impl %s",
self.def_id_to_str
(implementation.did));
self.add_candidates_from_impl
(implementation, use_assignability);
}
@ -473,6 +477,14 @@ class lookup {
}
}
fn def_id_to_str(def_id: ast::def_id) -> ~str {
if def_id.crate == ast::local_crate {
node_id_to_str(self.tcx().items, def_id.node)
} else {
ast_map::path_to_str(csearch::get_item_path(self.tcx(), def_id))
}
}
fn write_mty_from_candidate(cand: candidate) -> method_map_entry {
let tcx = self.fcx.ccx.tcx;

View file

@ -154,9 +154,21 @@ class CoherenceChecker {
visit_crate(*crate, (), mk_simple_visitor(@{
visit_item: |item| {
#debug("(checking coherence) item '%s'", *item.ident);
alt item.node {
item_impl(_, associated_trait, self_type, _) {
self.check_implementation(item, associated_trait);
item_impl(_, associated_traits, self_type, _) {
// XXX: Accept an array of traits.
let optional_associated_trait;
if associated_traits.len() == 0 {
optional_associated_trait = none;
} else {
optional_associated_trait =
some(associated_traits[0]);
}
self.check_implementation(item,
optional_associated_trait);
}
_ {
// Nothing to do.
@ -189,6 +201,10 @@ class CoherenceChecker {
let self_type = self.crate_context.tcx.tcache.get(local_def(item.id));
alt optional_associated_trait {
none {
#debug("(checking implementation) no associated trait for \
item '%s'",
*item.ident);
alt get_base_type_def_id(self.inference_context,
item.span,
self_type.ty) {
@ -207,6 +223,12 @@ class CoherenceChecker {
some(associated_trait) {
let def = self.crate_context.tcx.def_map.get
(associated_trait.ref_id);
#debug("(checking implementation) adding impl for trait \
'%s', item '%s'",
ast_map::node_id_to_str(self.crate_context.tcx.items,
associated_trait.ref_id),
*item.ident);
let implementation = self.create_impl_from_item(item);
self.add_trait_method(def_id_of_def(def), implementation);
}
@ -362,7 +384,15 @@ class CoherenceChecker {
self.privileged_types.remove(privileged_type);
}
}
item_impl(_, optional_trait_ref, _, _) {
item_impl(_, associated_traits, _, _) {
// XXX: Accept an array of traits.
let optional_trait_ref;
if associated_traits.len() == 0 {
optional_trait_ref = none;
} else {
optional_trait_ref = some(associated_traits[0]);
}
alt self.base_type_def_ids.find(local_def(item.id)) {
none {
// Nothing to do.