Skip to content

Commit 88b65c9

Browse files
committed
Refactor the emit_vtable_methods code to be a bit cleaner in its use of
iterators.
1 parent 883551b commit 88b65c9

File tree

1 file changed

+65
-34
lines changed

1 file changed

+65
-34
lines changed

src/librustc_trans/trans/meth.rs

+65-34
Original file line numberDiff line numberDiff line change
@@ -771,9 +771,15 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
771771
impl_id: ast::DefId,
772772
substs: subst::Substs<'tcx>,
773773
param_substs: &'tcx subst::Substs<'tcx>)
774-
-> Vec<ValueRef> {
774+
-> Vec<ValueRef>
775+
{
775776
let tcx = ccx.tcx();
776777

778+
debug!("emit_vtable_methods(impl_id={}, substs={}, param_substs={})",
779+
impl_id.repr(tcx),
780+
substs.repr(tcx),
781+
param_substs.repr(tcx));
782+
777783
let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
778784
Some(t_id) => t_id.def_id,
779785
None => ccx.sess().bug("make_impl_vtable: don't know how to \
@@ -783,41 +789,66 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
783789
ty::populate_implementations_for_trait_if_necessary(tcx, trt_id);
784790

785791
let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id);
786-
trait_item_def_ids.iter().flat_map(|method_def_id| {
787-
let method_def_id = method_def_id.def_id();
788-
let name = ty::impl_or_trait_item(tcx, method_def_id).name();
789-
// The substitutions we have are on the impl, so we grab
790-
// the method type from the impl to substitute into.
791-
let m_id = method_with_name(ccx, impl_id, name);
792-
let ti = ty::impl_or_trait_item(tcx, m_id);
793-
match ti {
794-
ty::MethodTraitItem(m) => {
795-
debug!("(making impl vtable) emitting method {} at subst {}",
796-
m.repr(tcx),
797-
substs.repr(tcx));
798-
if m.generics.has_type_params(subst::FnSpace) ||
799-
ty::type_has_self(ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(m.fty.clone())))
800-
{
801-
debug!("(making impl vtable) method has self or type \
802-
params: {}",
803-
token::get_name(name));
804-
Some(C_null(Type::nil(ccx).ptr_to())).into_iter()
805-
} else {
806-
let fn_ref = trans_fn_ref_with_substs(
807-
ccx,
808-
m_id,
809-
ExprId(0),
810-
param_substs,
811-
substs.clone()).val;
812-
813-
Some(fn_ref).into_iter()
814-
}
792+
trait_item_def_ids
793+
.iter()
794+
795+
// Filter out the associated types.
796+
.filter_map(|item_def_id| {
797+
match *item_def_id {
798+
ty::MethodTraitItemId(def_id) => Some(def_id),
799+
ty::TypeTraitItemId(_) => None,
815800
}
816-
ty::TypeTraitItem(_) => {
817-
None.into_iter()
801+
})
802+
803+
// Now produce pointers for each remaining method. If the
804+
// method could never be called from this object, just supply
805+
// null.
806+
.map(|trait_method_def_id| {
807+
debug!("emit_vtable_methods: trait_method_def_id={}",
808+
trait_method_def_id.repr(tcx));
809+
810+
let trait_method_type = match ty::impl_or_trait_item(tcx, trait_method_def_id) {
811+
ty::MethodTraitItem(m) => m,
812+
ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
813+
};
814+
let name = trait_method_type.name;
815+
816+
debug!("emit_vtable_methods: trait_method_type={}",
817+
trait_method_type.repr(tcx));
818+
819+
// The substitutions we have are on the impl, so we grab
820+
// the method type from the impl to substitute into.
821+
let impl_method_def_id = method_with_name(ccx, impl_id, name);
822+
let impl_method_type = match ty::impl_or_trait_item(tcx, impl_method_def_id) {
823+
ty::MethodTraitItem(m) => m,
824+
ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
825+
};
826+
827+
debug!("emit_vtable_methods: m={}",
828+
impl_method_type.repr(tcx));
829+
830+
let nullptr = C_null(Type::nil(ccx).ptr_to());
831+
832+
if impl_method_type.generics.has_type_params(subst::FnSpace) {
833+
debug!("emit_vtable_methods: generic");
834+
return nullptr;
818835
}
819-
}
820-
}).collect()
836+
837+
let bare_fn_ty =
838+
ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(impl_method_type.fty.clone()));
839+
if ty::type_has_self(bare_fn_ty) {
840+
debug!("emit_vtable_methods: type_has_self {}",
841+
bare_fn_ty.repr(tcx));
842+
return nullptr;
843+
}
844+
845+
trans_fn_ref_with_substs(ccx,
846+
impl_method_def_id,
847+
ExprId(0),
848+
param_substs,
849+
substs.clone()).val
850+
})
851+
.collect()
821852
}
822853

823854
/// Generates the code to convert from a pointer (`Box<T>`, `&T`, etc) into an object

0 commit comments

Comments
 (0)