about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-16 16:49:37 -0700
committerbors <bors@rust-lang.org>2013-05-16 16:49:37 -0700
commitf89e00b3d149d78b8fe21251912d9c7fa78b9f15 (patch)
tree26574116677ce4e28257981fbf506f41a2f544b7
parent00eef96a007a817533e78860e97b251258177d5f (diff)
parent65b7903ba3aab91c68d09e192f907a68b7308ee4 (diff)
downloadrust-f89e00b3d149d78b8fe21251912d9c7fa78b9f15.tar.gz
rust-f89e00b3d149d78b8fe21251912d9c7fa78b9f15.zip
auto merge of #6543 : catamorphism/rust/traits-cleanup, r=nikomatsakis
r? @nikomatsakis Impls can implement either zero or one traits; this has been true
more or less since we removed classes. So I got rid of the comments
saying "we should support multiple traits" and changed the code to
make it clear that we don't. This is just cleanup, and doesn't break
any existing tests.
-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 fe1326fcdca..c51fba8a62b 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3883,23 +3883,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);
                     }