mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-25 21:34:18 +00:00
Refactor the emit_vtable_methods code to be a bit cleaner in its use of
iterators.
This commit is contained in:
parent
883551b1d7
commit
88b65c9e2b
@ -771,9 +771,15 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
impl_id: ast::DefId,
|
||||
substs: subst::Substs<'tcx>,
|
||||
param_substs: &'tcx subst::Substs<'tcx>)
|
||||
-> Vec<ValueRef> {
|
||||
-> Vec<ValueRef>
|
||||
{
|
||||
let tcx = ccx.tcx();
|
||||
|
||||
debug!("emit_vtable_methods(impl_id={}, substs={}, param_substs={})",
|
||||
impl_id.repr(tcx),
|
||||
substs.repr(tcx),
|
||||
param_substs.repr(tcx));
|
||||
|
||||
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 \
|
||||
@ -783,41 +789,66 @@ fn emit_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ty::populate_implementations_for_trait_if_necessary(tcx, trt_id);
|
||||
|
||||
let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id);
|
||||
trait_item_def_ids.iter().flat_map(|method_def_id| {
|
||||
let method_def_id = method_def_id.def_id();
|
||||
let name = ty::impl_or_trait_item(tcx, method_def_id).name();
|
||||
// The substitutions we have are on the impl, so we grab
|
||||
// the method type from the impl to substitute into.
|
||||
let m_id = method_with_name(ccx, impl_id, name);
|
||||
let ti = ty::impl_or_trait_item(tcx, m_id);
|
||||
match ti {
|
||||
ty::MethodTraitItem(m) => {
|
||||
debug!("(making impl vtable) emitting method {} at subst {}",
|
||||
m.repr(tcx),
|
||||
substs.repr(tcx));
|
||||
if m.generics.has_type_params(subst::FnSpace) ||
|
||||
ty::type_has_self(ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(m.fty.clone())))
|
||||
{
|
||||
debug!("(making impl vtable) method has self or type \
|
||||
params: {}",
|
||||
token::get_name(name));
|
||||
Some(C_null(Type::nil(ccx).ptr_to())).into_iter()
|
||||
} else {
|
||||
let fn_ref = trans_fn_ref_with_substs(
|
||||
ccx,
|
||||
m_id,
|
||||
ExprId(0),
|
||||
param_substs,
|
||||
substs.clone()).val;
|
||||
trait_item_def_ids
|
||||
.iter()
|
||||
|
||||
Some(fn_ref).into_iter()
|
||||
}
|
||||
// Filter out the associated types.
|
||||
.filter_map(|item_def_id| {
|
||||
match *item_def_id {
|
||||
ty::MethodTraitItemId(def_id) => Some(def_id),
|
||||
ty::TypeTraitItemId(_) => None,
|
||||
}
|
||||
ty::TypeTraitItem(_) => {
|
||||
None.into_iter()
|
||||
})
|
||||
|
||||
// Now produce pointers for each remaining method. If the
|
||||
// method could never be called from this object, just supply
|
||||
// null.
|
||||
.map(|trait_method_def_id| {
|
||||
debug!("emit_vtable_methods: trait_method_def_id={}",
|
||||
trait_method_def_id.repr(tcx));
|
||||
|
||||
let trait_method_type = match ty::impl_or_trait_item(tcx, trait_method_def_id) {
|
||||
ty::MethodTraitItem(m) => m,
|
||||
ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
|
||||
};
|
||||
let name = trait_method_type.name;
|
||||
|
||||
debug!("emit_vtable_methods: trait_method_type={}",
|
||||
trait_method_type.repr(tcx));
|
||||
|
||||
// The substitutions we have are on the impl, so we grab
|
||||
// the method type from the impl to substitute into.
|
||||
let impl_method_def_id = method_with_name(ccx, impl_id, name);
|
||||
let impl_method_type = match ty::impl_or_trait_item(tcx, impl_method_def_id) {
|
||||
ty::MethodTraitItem(m) => m,
|
||||
ty::TypeTraitItem(_) => ccx.sess().bug("should be a method, not assoc type")
|
||||
};
|
||||
|
||||
debug!("emit_vtable_methods: m={}",
|
||||
impl_method_type.repr(tcx));
|
||||
|
||||
let nullptr = C_null(Type::nil(ccx).ptr_to());
|
||||
|
||||
if impl_method_type.generics.has_type_params(subst::FnSpace) {
|
||||
debug!("emit_vtable_methods: generic");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}).collect()
|
||||
|
||||
let bare_fn_ty =
|
||||
ty::mk_bare_fn(tcx, None, tcx.mk_bare_fn(impl_method_type.fty.clone()));
|
||||
if ty::type_has_self(bare_fn_ty) {
|
||||
debug!("emit_vtable_methods: type_has_self {}",
|
||||
bare_fn_ty.repr(tcx));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
trans_fn_ref_with_substs(ccx,
|
||||
impl_method_def_id,
|
||||
ExprId(0),
|
||||
param_substs,
|
||||
substs.clone()).val
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Generates the code to convert from a pointer (`Box<T>`, `&T`, etc) into an object
|
||||
|
Loading…
Reference in New Issue
Block a user