Skip to content

Commit

Permalink
auto merge of rust-lang#6543 : catamorphism/rust/traits-cleanup, r=ni…
Browse files Browse the repository at this point in the history
…komatsakis

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.
  • Loading branch information
bors committed May 16, 2013
2 parents 00eef96 + 65b7903 commit f89e00b
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 40 deletions.
11 changes: 5 additions & 6 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
11 changes: 6 additions & 5 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 5 additions & 2 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
28 changes: 11 additions & 17 deletions src/librustc/middle/typeck/check/vtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/typeck/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit f89e00b

Please sign in to comment.