diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index e6b8432854d32..5a0820202a99a 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 2592875cd5753..43073728e8351 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 bdbb45bf2755a..6eb2540f1df65 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 4ee2c5b01006f..c363fb7111b6a 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 42ab9d977292c..2e2b4550f6331 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, bar, quux { ... } - // - // then ty::impl_traits would return - // - // ~[baz, 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 c64a0235eb1f0..311aa551601dc 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); }