From 0145b15f0cd61389599eb1cb77c028f7f4a8229a Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Mon, 9 Jan 2012 17:44:55 +0100 Subject: [PATCH] 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. --- src/comp/middle/trans.rs | 9 ++++----- src/comp/middle/trans_impl.rs | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 2c5c45ed570..7fb21547589 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -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 t_kind(tcx: ty::ctxt, t: ty::t) -> kind { 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); } diff --git a/src/comp/middle/trans_impl.rs b/src/comp/middle/trans_impl.rs index 6b550a76c86..bb17553b2f0 100644 --- a/src/comp/middle/trans_impl.rs +++ b/src/comp/middle/trans_impl.rs @@ -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)) {