Make trans give correct types to monomorphic dtors
Irritatingly, class dtors have a different type from resource dtors (because class dtors have a self argument), and the monomorphic case wasn't reflecting that. Fixed.
This commit is contained in:
parent
0017116520
commit
b02172971f
@ -754,7 +754,8 @@ fn trans_class_drop(bcx: block, v0: ValueRef, dtor_did: ast::def_id,
|
||||
// We have to cast v0
|
||||
let classptr = GEPi(bcx, v0, [0u, 1u]);
|
||||
// Find and call the actual destructor
|
||||
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, substs.tps);
|
||||
let dtor_addr = get_res_dtor(bcx.ccx(), dtor_did, some(class_did),
|
||||
substs.tps);
|
||||
// The second argument is the "self" argument for drop
|
||||
let params = lib::llvm::fn_ty_param_tys
|
||||
(llvm::LLVMGetElementType
|
||||
@ -829,7 +830,11 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
|
||||
build_return(bcx);
|
||||
}
|
||||
|
||||
fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
|
||||
fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id,
|
||||
// Parent ID is an option because resources don't
|
||||
// have one. We can make this a def_id when
|
||||
// resources get removed.
|
||||
opt_id: option<ast::def_id>, substs: [ty::t])
|
||||
-> ValueRef {
|
||||
let _icx = ccx.insn_ctxt("trans_res_dtor");
|
||||
if (substs.len() > 0u) {
|
||||
@ -841,14 +846,27 @@ fn get_res_dtor(ccx: @crate_ctxt, did: ast::def_id, substs: [ty::t])
|
||||
} else if did.crate == ast::local_crate {
|
||||
get_item_val(ccx, did.node)
|
||||
} else {
|
||||
let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_bare,
|
||||
inputs: [{mode: ast::expl(ast::by_ref),
|
||||
alt opt_id {
|
||||
some(parent_id) {
|
||||
let tcx = ccx.tcx;
|
||||
let name = csearch::get_symbol(ccx.sess.cstore, did);
|
||||
let class_ty = ty::subst_tps(tcx, substs,
|
||||
ty::lookup_item_type(tcx, parent_id).ty);
|
||||
let llty = type_of_dtor(ccx, class_ty);
|
||||
get_extern_fn(ccx.externs, ccx.llmod, name, lib::llvm::CCallConv,
|
||||
llty)
|
||||
}
|
||||
none {
|
||||
let fty = ty::mk_fn(ccx.tcx, {purity: ast::impure_fn,
|
||||
proto: ast::proto_bare,
|
||||
inputs: [{mode: ast::expl(ast::by_ref),
|
||||
ty: ty::mk_nil_ptr(ccx.tcx)}],
|
||||
output: ty::mk_nil(ccx.tcx),
|
||||
ret_style: ast::return_val,
|
||||
constraints: []});
|
||||
trans_external_path(ccx, did, fty)
|
||||
trans_external_path(ccx, did, fty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,7 +880,7 @@ fn trans_res_drop(bcx: block, rs: ValueRef, did: ast::def_id,
|
||||
with_cond(bcx, IsNotNull(bcx, Load(bcx, drop_flag))) {|bcx|
|
||||
let valptr = GEPi(bcx, rs, [0u, 1u]);
|
||||
// Find and call the actual destructor.
|
||||
let dtor_addr = get_res_dtor(ccx, did, tps);
|
||||
let dtor_addr = get_res_dtor(ccx, did, none, tps);
|
||||
let args = [bcx.fcx.llretptr, null_env_ptr(bcx)];
|
||||
// Kludge to work around the fact that we know the precise type of the
|
||||
// value here, but the dtor expects a type that might have opaque
|
||||
|
@ -21,12 +21,14 @@ import std::map::hashmap;
|
||||
|
||||
import ty_ctxt = middle::ty::ctxt;
|
||||
|
||||
type nominal_id = @{did: ast::def_id, tps: [ty::t]};
|
||||
type nominal_id = @{did: ast::def_id, parent_id: option<ast::def_id>,
|
||||
tps: [ty::t]};
|
||||
|
||||
fn mk_nominal_id(tcx: ty::ctxt, did: ast::def_id,
|
||||
parent_id: option<ast::def_id>,
|
||||
tps: [ty::t]) -> nominal_id {
|
||||
let tps_norm = tps.map { |t| ty::normalize_ty(tcx, t) };
|
||||
@{did: did, tps: tps_norm}
|
||||
@{did: did, parent_id: parent_id, tps: tps_norm}
|
||||
}
|
||||
|
||||
fn hash_nominal_id(&&ri: nominal_id) -> uint {
|
||||
@ -233,7 +235,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
tk_enum { [s_variant_enum_t(ccx.tcx)] }
|
||||
tk_newtype | tk_complex {
|
||||
let mut s = [shape_enum], id;
|
||||
let nom_id = mk_nominal_id(ccx.tcx, did, substs.tps);
|
||||
let nom_id = mk_nominal_id(ccx.tcx, did, none, substs.tps);
|
||||
alt ccx.shape_cx.tag_id_to_index.find(nom_id) {
|
||||
none {
|
||||
id = ccx.shape_cx.next_tag_id;
|
||||
@ -335,7 +337,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
else { [shape_struct] };
|
||||
let mut sub = [];
|
||||
option::iter(m_dtor_did) {|dtor_did|
|
||||
let ri = @{did: dtor_did, tps: tps};
|
||||
let ri = @{did: dtor_did, parent_id: some(did), tps: tps};
|
||||
let id = interner::intern(ccx.shape_cx.resources, ri);
|
||||
add_u16(s, id as u16);
|
||||
|
||||
@ -362,7 +364,7 @@ fn shape_of(ccx: @crate_ctxt, t: ty::t) -> [u8] {
|
||||
for substs.tps.each() {|t| assert !ty::type_has_params(t); }
|
||||
let subt = ty::subst(ccx.tcx, substs, raw_subt);
|
||||
let tps = substs.tps;
|
||||
let ri = @{did: did, tps: tps};
|
||||
let ri = @{did: did, parent_id: none, tps: tps};
|
||||
let id = interner::intern(ccx.shape_cx.resources, ri);
|
||||
|
||||
let mut s = [shape_res];
|
||||
@ -597,7 +599,8 @@ fn gen_resource_shapes(ccx: @crate_ctxt) -> ValueRef {
|
||||
for uint::range(0u, len) {|i|
|
||||
let ri = interner::get(ccx.shape_cx.resources, i);
|
||||
for ri.tps.each() {|s| assert !ty::type_has_params(s); }
|
||||
dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.tps)];
|
||||
dtors += [trans::base::get_res_dtor(ccx, ri.did, ri.parent_id,
|
||||
ri.tps)];
|
||||
}
|
||||
ret mk_global(ccx, "resource_shapes", C_struct(dtors), true);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import std::map::hashmap;
|
||||
import ty::*;
|
||||
|
||||
export type_of;
|
||||
export type_of_dtor;
|
||||
export type_of_explicit_args;
|
||||
export type_of_fn_from_ty;
|
||||
export type_of_fn;
|
||||
@ -251,3 +252,9 @@ fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str {
|
||||
);
|
||||
}
|
||||
|
||||
fn type_of_dtor(ccx: @crate_ctxt, self_ty: ty::t) -> TypeRef {
|
||||
T_fn([T_ptr(type_of(ccx, ty::mk_nil(ccx.tcx))),
|
||||
T_ptr(type_of(ccx, self_ty))],
|
||||
llvm::LLVMVoidType())
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user