about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/metadata/csearch.rs11
-rw-r--r--src/librustc/metadata/decoder.rs11
-rw-r--r--src/librustc/middle/trans/meth.rs7
-rw-r--r--src/librustc/middle/ty.rs12
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs28
-rw-r--r--src/librustc/middle/typeck/coherence.rs8
6 files changed, 37 insertions, 40 deletions
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index e6b8432854d..5a0820202a9 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -234,14 +234,13 @@ pub fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
     }
 }
 
-// Given a def_id for an impl or class, return the traits it implements,
-// or the empty vector if it's not for an impl or for a class that implements
-// traits
-pub fn get_impl_traits(tcx: ty::ctxt,
-                       def: ast::def_id) -> ~[@ty::TraitRef] {
+// Given a def_id for an impl, return the trait it implements,
+// if there is one.
+pub fn get_impl_trait(tcx: ty::ctxt,
+                      def: ast::def_id) -> Option<@ty::TraitRef> {
     let cstore = tcx.cstore;
     let cdata = cstore::get_crate_data(cstore, def.crate);
-    decoder::get_impl_traits(cdata, def.node, tcx)
+    decoder::get_impl_trait(cdata, def.node, tcx)
 }
 
 pub fn get_impl_method(cstore: @mut cstore::CStore,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 2592875cd57..43073728e83 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -415,19 +415,20 @@ pub fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint {
     item_ty_param_count(lookup_item(id, data))
 }
 
-pub fn get_impl_traits(cdata: cmd,
+pub fn get_impl_trait(cdata: cmd,
                        id: ast::node_id,
-                       tcx: ty::ctxt) -> ~[@ty::TraitRef]
+                       tcx: ty::ctxt) -> Option<@ty::TraitRef>
 {
     let item_doc = lookup_item(id, cdata.data);
-    let mut results = ~[];
+    let mut result = None;
     for reader::tagged_docs(item_doc, tag_item_trait_ref) |tp| {
         let trait_ref =
             @parse_trait_ref_data(tp.data, cdata.cnum, tp.start, tcx,
                                   |_, did| translate_def_id(cdata, did));
-        results.push(trait_ref);
+        result = Some(trait_ref);
+        break;
     };
-    results
+    result
 }
 
 pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index bdbb45bf275..6eb2540f1df 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -795,8 +795,11 @@ pub fn make_impl_vtable(ccx: @CrateContext,
     let _icx = ccx.insn_ctxt("impl::make_impl_vtable");
     let tcx = ccx.tcx;
 
-    // XXX: This should support multiple traits.
-    let trt_id = ty::impl_trait_refs(tcx, impl_id)[0].def_id;
+    let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
+        Some(t_id) => t_id.def_id,
+        None       => ccx.sess.bug("make_impl_vtable: don't know how to \
+                                    make a vtable for a type impl!")
+    };
 
     let has_tps =
         !ty::lookup_item_type(ccx.tcx, impl_id).generics.type_param_defs.is_empty();
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 4ee2c5b0100..c363fb7111b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3878,23 +3878,23 @@ pub fn trait_method_def_ids(cx: ctxt, id: ast::def_id) -> @~[def_id] {
         || @csearch::get_trait_method_def_ids(cx.cstore, id))
 }
 
-pub fn impl_trait_refs(cx: ctxt, id: ast::def_id) -> ~[@TraitRef] {
+pub fn impl_trait_ref(cx: ctxt, id: ast::def_id) -> Option<@TraitRef> {
     if id.crate == ast::local_crate {
-        debug!("(impl_traits) searching for trait impl %?", id);
+        debug!("(impl_trait_ref) searching for trait impl %?", id);
         match cx.items.find(&id.node) {
            Some(&ast_map::node_item(@ast::item {
                         node: ast::item_impl(_, opt_trait, _, _),
                         _},
                     _)) => {
                match opt_trait {
-                   Some(t) => ~[ty::node_id_to_trait_ref(cx, t.ref_id)],
-                   None => ~[]
+                   Some(t) => Some(ty::node_id_to_trait_ref(cx, t.ref_id)),
+                   None => None
                }
            }
-           _ => ~[]
+           _ => None
         }
     } else {
-        csearch::get_impl_traits(cx, id)
+        csearch::get_impl_trait(cx, id)
     }
 }
 
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 42ab9d97729..2e2b4550f63 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -261,24 +261,14 @@ fn lookup_vtable(vcx: &VtableContext,
                         }
                         impls_seen.insert(im.did);
 
-                        // ty::impl_traits gives us the list of all
-                        // traits that im implements. Again, usually
-                        // there's just one.
+                        // ty::impl_traits gives us the trait im implements,
+                        // if there is one (there's either zero or one).
                         //
-                        // For example, if im represented the struct
-                        // in:
-                        //
-                        //   struct foo : baz<int>, bar, quux { ... }
-                        //
-                        // then ty::impl_traits would return
-                        //
-                        //   ~[baz<int>, bar, quux]
-                        //
-                        // For each of the traits foo implements, if
-                        // it's the same trait as trait_ref, we need to
+                        // If foo implements a trait t, and if t is the
+                        // same trait as trait_ref, we need to
                         // unify it with trait_ref in order to get all
                         // the ty vars sorted out.
-                        for ty::impl_trait_refs(tcx, im.did).each |&of_trait_ref|
+                        for ty::impl_trait_ref(tcx, im.did).each |&of_trait_ref|
                         {
                             if of_trait_ref.def_id != trait_ref.def_id { loop; }
 
@@ -456,8 +446,12 @@ fn connect_trait_tps(vcx: &VtableContext,
 {
     let tcx = vcx.tcx();
 
-    // XXX: This should work for multiple traits.
-    let impl_trait_ref = ty::impl_trait_refs(tcx, impl_did)[0];
+    let impl_trait_ref = match ty::impl_trait_ref(tcx, impl_did) {
+        Some(t) => t,
+        None => vcx.tcx().sess.span_bug(location_info.span,
+                                  "connect_trait_tps invoked on a type impl")
+    };
+
     let impl_trait_ref = (*impl_trait_ref).subst(tcx, impl_substs);
     relate_trait_refs(vcx, location_info, &impl_trait_ref, trait_ref);
 }
diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs
index c64a0235eb1..311aa551601 100644
--- a/src/librustc/middle/typeck/coherence.rs
+++ b/src/librustc/middle/typeck/coherence.rs
@@ -16,7 +16,7 @@
 
 
 use driver;
-use metadata::csearch::{each_path, get_impl_traits};
+use metadata::csearch::{each_path, get_impl_trait};
 use metadata::csearch::{get_impls_for_mod};
 use metadata::csearch;
 use metadata::cstore::{CStore, iter_crate_data};
@@ -898,13 +898,13 @@ pub impl CoherenceChecker {
 
             let self_type = lookup_item_type(self.crate_context.tcx,
                                              implementation.did);
-            let associated_traits = get_impl_traits(self.crate_context.tcx,
+            let associated_traits = get_impl_trait(self.crate_context.tcx,
                                                     implementation.did);
 
             // Do a sanity check to make sure that inherent methods have base
             // types.
 
-            if associated_traits.len() == 0 {
+            if associated_traits.is_none() {
                 match get_base_type_def_id(self.inference_context,
                                            dummy_sp(),
                                            self_type.ty) {
@@ -940,7 +940,7 @@ pub impl CoherenceChecker {
                 Some(base_type_def_id) => {
                     // inherent methods apply to `impl Type` but not
                     // `impl Trait for Type`:
-                    if associated_traits.len() == 0 {
+                    if associated_traits.is_none() {
                         self.add_inherent_method(base_type_def_id,
                                                  *implementation);
                     }