diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-07-18 09:31:53 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-07-18 16:05:17 -0700 |
| commit | 3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac (patch) | |
| tree | 0613184ab1f468f2a1b776c1d4c6df4ac15d69db /src/rustc | |
| parent | 1528256fdc26199dd58b390e42e2d0dc53b9703d (diff) | |
| download | rust-3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac.tar.gz rust-3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac.zip | |
syntax: Parse multiple trait refs in a single implementation
Diffstat (limited to 'src/rustc')
| -rw-r--r-- | src/rustc/metadata/encoder.rs | 20 | ||||
| -rw-r--r-- | src/rustc/middle/resolve3.rs | 20 | ||||
| -rw-r--r-- | src/rustc/middle/ty.rs | 9 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/check/method.rs | 14 | ||||
| -rw-r--r-- | src/rustc/middle/typeck/coherence.rs | 36 |
5 files changed, 72 insertions, 27 deletions
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 4df1e0aa513..e11008f4d6f 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -410,14 +410,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod, ref, we need to map it to its parent class */ ebml_w.wr_str(def_to_str(local_def(it.id))); } - some(ast_map::node_item(@{node: item_impl(_, - some(ifce),_,_),_},_)) { - ebml_w.wr_str(def_to_str(did)); - } - some(_) { - ebml_w.wr_str(def_to_str(did)); - } - none { + _ { // Must be a re-export, then! // ...or an iface ref ebml_w.wr_str(def_to_str(did)); @@ -715,7 +708,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_index(ebml_w, bkts, write_int); ebml_w.end_tag(); } - item_impl(tps, ifce, _, methods) { + item_impl(tps, traits, _, methods) { add_to_index(); ebml_w.start_tag(tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); @@ -729,9 +722,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id)))); ebml_w.end_tag(); } - do option::iter(ifce) |t| { - encode_trait_ref(ebml_w, ecx, t) - }; + if traits.len() > 1 { + fail ~"multiple traits!!"; + } + for traits.each |associated_trait| { + encode_trait_ref(ebml_w, ecx, associated_trait) + } encode_path(ebml_w, path, ast_map::path_name(item.ident)); ebml_w.end_tag(); diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index 04a7448f798..55bc99fa688 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -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) { diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 08ef9fb6bff..b750870ff86 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -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(*), _},_)) { diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs index c2135249c9c..7f269944059 100644 --- a/src/rustc/middle/typeck/check/method.rs +++ b/src/rustc/middle/typeck/check/method.rs @@ -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; diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs index 19b4450bb62..f0c70cbc3a9 100644 --- a/src/rustc/middle/typeck/coherence.rs +++ b/src/rustc/middle/typeck/coherence.rs @@ -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. |
