diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index c5a6769d30562..221a95370451e 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1745,7 +1745,7 @@ type lval_result = {bcx: block, val: ValueRef, kind: lval_kind}; enum callee_env { null_env, is_closure, - self_env(ValueRef, ty::t), + self_env(ValueRef, ty::t, option), } type lval_maybe_callee = {bcx: block, val: ValueRef, @@ -2341,7 +2341,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result { } fn lval_maybe_callee_to_lval(c: lval_maybe_callee, ty: ty::t) -> lval_result { - let must_bind = alt c.env { self_env(_, _) { true } _ { false } }; + let must_bind = alt c.env { self_env(_, _, _) { true } _ { false } }; if must_bind { let n_args = ty::ty_fn_args(ty).len(); let args = vec::from_elem(n_args, none); @@ -2618,7 +2618,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, null_env { llvm::LLVMGetUndef(T_opaque_box_ptr(ccx)) } - self_env(e, _) { + self_env(e, _, _) { PointerCast(bcx, e, T_opaque_box_ptr(ccx)) } is_closure { diff --git a/src/rustc/middle/trans/closure.rs b/src/rustc/middle/trans/closure.rs index d579d4c569c42..e254671773281 100644 --- a/src/rustc/middle/trans/closure.rs +++ b/src/rustc/middle/trans/closure.rs @@ -462,8 +462,13 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t, let src_loc = PointerCast(bcx, f_res.val, llclosurety); ([env_copy(src_loc, pair_ty, owned)], target_closure) } - self_env(slf, slf_t) { - ([env_copy(slf, slf_t, owned)], target_self(f_res.val)) + self_env(slf, slf_t, none) { + ([env_copy(slf, slf_t, owned)], target_static_self(f_res.val)) + } + self_env(_, slf_t, some(slf)) { + let cast = PointerCast(bcx, f_res.val, T_ptr(T_nil())); + ([env_copy(cast, ty::mk_nil_ptr(ccx.tcx), owned_imm), + env_copy(slf, slf_t, owned_imm)], target_self) } }; @@ -617,7 +622,8 @@ fn make_opaque_cbox_free_glue( enum target_info { target_closure, target_static(ValueRef), - target_self(ValueRef), + target_self, + target_static_self(ValueRef), } // pth is cx.path @@ -698,7 +704,14 @@ fn trans_bind_thunk(ccx: @crate_ctxt, (bcx, GEPi(bcx, pair, [0, abi::fn_field_code])); (lltargetfn, lltargetenv, 1) } - target_self(fptr) { + target_self { + let fptr = Load(bcx, GEPi(bcx, llcdata, + [0, abi::closure_body_bindings, 0])); + let slfbox = GEPi(bcx, llcdata, [0, abi::closure_body_bindings, 1]); + let selfptr = GEPi(bcx, Load(bcx, slfbox), [0, abi::box_field_body]); + (fptr, PointerCast(bcx, selfptr, T_opaque_cbox_ptr(ccx)), 2) + } + target_static_self(fptr) { let slfptr = GEPi(bcx, llcdata, [0, abi::closure_body_bindings, 0]); (fptr, PointerCast(bcx, slfptr, T_opaque_cbox_ptr(ccx)), 1) } diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index faa9066cf5c51..f706c0b0471a1 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -49,7 +49,7 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id, alt origin { typeck::method_static(did) { let {bcx, val} = trans_self_arg(bcx, self); - {env: self_env(val, node_id_type(bcx, self.id)) + {env: self_env(val, node_id_type(bcx, self.id), none) with lval_static_fn(bcx, did, callee_id)} } typeck::method_param(iid, off, p, b) { @@ -115,7 +115,7 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id, let ty_substs = impl_substs + vec::tailn(node_substs, node_substs.len() - n_m_tps); let {bcx, val} = trans_self_arg(bcx, base); - {env: self_env(val, node_id_type(bcx, base.id)) + {env: self_env(val, node_id_type(bcx, base.id), none) with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs, some(sub_origins))} } @@ -138,8 +138,8 @@ fn trans_iface_callee(bcx: block, base: @ast::expr, let box = Load(bcx, GEPi(bcx, val, [0, 1])); // FIXME[impl] I doubt this is alignment-safe let self = GEPi(bcx, box, [0, abi::box_field_body]); - trans_vtable_callee(bcx, self_env(self, expr_ty(bcx, base)), vtable, - callee_id, n_method) + let env = self_env(self, ty::mk_opaque_box(bcx.tcx()), some(box)); + trans_vtable_callee(bcx, env, vtable, callee_id, n_method) } fn find_vtable_in_fn_ctxt(ps: param_substs, n_param: uint, n_bound: uint) diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index 3518a4d1f0e62..32be4ee5518cf 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -77,7 +77,7 @@ export ty_nil, mk_nil, type_is_nil; export ty_iface, mk_iface; export ty_res, mk_res; export ty_param, mk_param; -export ty_ptr, mk_ptr, mk_mut_ptr, type_is_unsafe_ptr; +export ty_ptr, mk_ptr, mk_mut_ptr, mk_nil_ptr, type_is_unsafe_ptr; export ty_rptr, mk_rptr; export ty_rec, mk_rec; export ty_enum, mk_enum, type_is_enum; @@ -482,6 +482,10 @@ fn mk_rptr(cx: ctxt, r: region, tm: mt) -> t { mk_t(cx, ty_rptr(r, tm)) } fn mk_mut_ptr(cx: ctxt, ty: t) -> t { mk_ptr(cx, {ty: ty, mutbl: ast::m_mutbl}) } +fn mk_nil_ptr(cx: ctxt) -> t { + mk_ptr(cx, {ty: mk_nil(cx), mutbl: ast::m_imm}) +} + fn mk_vec(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_vec(tm)) } fn mk_rec(cx: ctxt, fs: [field]) -> t { mk_t(cx, ty_rec(fs)) }