about summary refs log tree commit diff
path: root/src/rustc
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2012-07-18 09:31:53 -0700
committerPatrick Walton <pcwalton@mimiga.net>2012-07-18 16:05:17 -0700
commit3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac (patch)
tree0613184ab1f468f2a1b776c1d4c6df4ac15d69db /src/rustc
parent1528256fdc26199dd58b390e42e2d0dc53b9703d (diff)
downloadrust-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.rs20
-rw-r--r--src/rustc/middle/resolve3.rs20
-rw-r--r--src/rustc/middle/ty.rs9
-rw-r--r--src/rustc/middle/typeck/check/method.rs14
-rw-r--r--src/rustc/middle/typeck/coherence.rs36
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.