Skip to content

rustc: Change ty::get_impl_traits to return an option instead of a vec #6543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -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)
}
}

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