Pass type with params intact as item_type for method callees

This prevents trans_args from optimizing out nil return types. The
method might be generic, in which case it *will* write to a nil retptr.
This commit is contained in:
Marijn Haverbeke 2012-01-09 17:44:55 +01:00
parent ef895b9632
commit 0145b15f0c
2 changed files with 6 additions and 7 deletions

View file

@ -1313,7 +1313,7 @@ fn make_take_glue(cx: @block_ctxt, v: ValueRef, t: ty::t) {
let tcx = bcx_tcx(cx);
// NB: v is an *alias* of type t here, not a direct value.
bcx = alt ty::struct(tcx, t) {
ty::ty_box(_) {
ty::ty_box(_) | ty::ty_iface(_, _) {
incr_refcnt_of_boxed(bcx, Load(bcx, v))
}
ty::ty_uniq(_) {
@ -3078,7 +3078,7 @@ fn trans_cast(cx: @block_ctxt, e: @ast::expr, id: ast::node_id,
ret store_in_dest(e_res.bcx, newval, dest);
}
fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef,
&to_zero: [{v: ValueRef, t: ty::t}],
&to_revoke: [{v: ValueRef, t: ty::t}], e: @ast::expr) ->
result {
@ -3092,8 +3092,8 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
// For values of type _|_, we generate an
// "undef" value, as such a value should never
// be inspected. It's important for the value
// to have type lldestty0 (the callee's expected type).
val = llvm::LLVMGetUndef(lldestty0);
// to have type lldestty (the callee's expected type).
val = llvm::LLVMGetUndef(lldestty);
} else if arg.mode == ast::by_ref || arg.mode == ast::by_val {
let copied = false, imm = ty::type_is_immediate(ccx.tcx, e_ty);
if arg.mode == ast::by_ref && lv.kind != owned && imm {
@ -3134,7 +3134,6 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
}
if !is_bot && ty::type_contains_params(ccx.tcx, arg.ty) {
let lldestty = lldestty0;
val = PointerCast(bcx, val, lldestty);
}

View file

@ -73,7 +73,7 @@ fn trans_vtable_callee(bcx: @block_ctxt, self: ValueRef, dict: ValueRef,
n_method: uint) -> lval_maybe_callee {
let bcx = bcx, ccx = bcx_ccx(bcx), tcx = ccx.tcx;
let method = ty::iface_methods(tcx, iface_id)[n_method];
let fty = ty::expr_ty(tcx, fld_expr);
let fty = ty::mk_fn(tcx, method.fty);
let bare_fn_ty = type_of_fn_from_ty(ccx, ast_util::dummy_sp(),
fty, *method.tps);
let {inputs: bare_inputs, output} = llfn_arg_tys(bare_fn_ty);
@ -82,7 +82,7 @@ fn trans_vtable_callee(bcx: @block_ctxt, self: ValueRef, dict: ValueRef,
T_ptr(T_array(T_ptr(fn_ty), n_method + 1u)));
let mptr = Load(bcx, GEPi(bcx, vtable, [0, n_method as int]));
let generic = none;
if vec::len(*method.tps) > 0u {
if vec::len(*method.tps) > 0u || ty::type_contains_params(tcx, fty) {
let tydescs = [], tis = [];
let tptys = ty::node_id_to_type_params(tcx, fld_expr.id);
for t in vec::tail_n(tptys, vec::len(tptys) - vec::len(*method.tps)) {