Skip to content

Commit 15a325f

Browse files
committed
Support binding of methods off boxed iface values
Closes rust-lang#435
1 parent 5f20c94 commit 15a325f

File tree

4 files changed

+29
-12
lines changed

4 files changed

+29
-12
lines changed

src/rustc/middle/trans/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,7 +1745,7 @@ type lval_result = {bcx: block, val: ValueRef, kind: lval_kind};
17451745
enum callee_env {
17461746
null_env,
17471747
is_closure,
1748-
self_env(ValueRef, ty::t),
1748+
self_env(ValueRef, ty::t, option<ValueRef>),
17491749
}
17501750
type lval_maybe_callee = {bcx: block,
17511751
val: ValueRef,
@@ -2341,7 +2341,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
23412341
}
23422342

23432343
fn lval_maybe_callee_to_lval(c: lval_maybe_callee, ty: ty::t) -> lval_result {
2344-
let must_bind = alt c.env { self_env(_, _) { true } _ { false } };
2344+
let must_bind = alt c.env { self_env(_, _, _) { true } _ { false } };
23452345
if must_bind {
23462346
let n_args = ty::ty_fn_args(ty).len();
23472347
let args = vec::from_elem(n_args, none);
@@ -2618,7 +2618,7 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
26182618
null_env {
26192619
llvm::LLVMGetUndef(T_opaque_box_ptr(ccx))
26202620
}
2621-
self_env(e, _) {
2621+
self_env(e, _, _) {
26222622
PointerCast(bcx, e, T_opaque_box_ptr(ccx))
26232623
}
26242624
is_closure {

src/rustc/middle/trans/closure.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,13 @@ fn trans_bind_1(cx: block, outgoing_fty: ty::t,
462462
let src_loc = PointerCast(bcx, f_res.val, llclosurety);
463463
([env_copy(src_loc, pair_ty, owned)], target_closure)
464464
}
465-
self_env(slf, slf_t) {
466-
([env_copy(slf, slf_t, owned)], target_self(f_res.val))
465+
self_env(slf, slf_t, none) {
466+
([env_copy(slf, slf_t, owned)], target_static_self(f_res.val))
467+
}
468+
self_env(_, slf_t, some(slf)) {
469+
let cast = PointerCast(bcx, f_res.val, T_ptr(T_nil()));
470+
([env_copy(cast, ty::mk_nil_ptr(ccx.tcx), owned_imm),
471+
env_copy(slf, slf_t, owned_imm)], target_self)
467472
}
468473
};
469474

@@ -617,7 +622,8 @@ fn make_opaque_cbox_free_glue(
617622
enum target_info {
618623
target_closure,
619624
target_static(ValueRef),
620-
target_self(ValueRef),
625+
target_self,
626+
target_static_self(ValueRef),
621627
}
622628

623629
// pth is cx.path
@@ -698,7 +704,14 @@ fn trans_bind_thunk(ccx: @crate_ctxt,
698704
(bcx, GEPi(bcx, pair, [0, abi::fn_field_code]));
699705
(lltargetfn, lltargetenv, 1)
700706
}
701-
target_self(fptr) {
707+
target_self {
708+
let fptr = Load(bcx, GEPi(bcx, llcdata,
709+
[0, abi::closure_body_bindings, 0]));
710+
let slfbox = GEPi(bcx, llcdata, [0, abi::closure_body_bindings, 1]);
711+
let selfptr = GEPi(bcx, Load(bcx, slfbox), [0, abi::box_field_body]);
712+
(fptr, PointerCast(bcx, selfptr, T_opaque_cbox_ptr(ccx)), 2)
713+
}
714+
target_static_self(fptr) {
702715
let slfptr = GEPi(bcx, llcdata, [0, abi::closure_body_bindings, 0]);
703716
(fptr, PointerCast(bcx, slfptr, T_opaque_cbox_ptr(ccx)), 1)
704717
}

src/rustc/middle/trans/impl.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
4949
alt origin {
5050
typeck::method_static(did) {
5151
let {bcx, val} = trans_self_arg(bcx, self);
52-
{env: self_env(val, node_id_type(bcx, self.id))
52+
{env: self_env(val, node_id_type(bcx, self.id), none)
5353
with lval_static_fn(bcx, did, callee_id)}
5454
}
5555
typeck::method_param(iid, off, p, b) {
@@ -115,7 +115,7 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
115115
let ty_substs = impl_substs +
116116
vec::tailn(node_substs, node_substs.len() - n_m_tps);
117117
let {bcx, val} = trans_self_arg(bcx, base);
118-
{env: self_env(val, node_id_type(bcx, base.id))
118+
{env: self_env(val, node_id_type(bcx, base.id), none)
119119
with lval_static_fn_inner(bcx, mth_id, callee_id, ty_substs,
120120
some(sub_origins))}
121121
}
@@ -138,8 +138,8 @@ fn trans_iface_callee(bcx: block, base: @ast::expr,
138138
let box = Load(bcx, GEPi(bcx, val, [0, 1]));
139139
// FIXME[impl] I doubt this is alignment-safe
140140
let self = GEPi(bcx, box, [0, abi::box_field_body]);
141-
trans_vtable_callee(bcx, self_env(self, expr_ty(bcx, base)), vtable,
142-
callee_id, n_method)
141+
let env = self_env(self, ty::mk_opaque_box(bcx.tcx()), some(box));
142+
trans_vtable_callee(bcx, env, vtable, callee_id, n_method)
143143
}
144144

145145
fn find_vtable_in_fn_ctxt(ps: param_substs, n_param: uint, n_bound: uint)

src/rustc/middle/ty.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export ty_nil, mk_nil, type_is_nil;
7777
export ty_iface, mk_iface;
7878
export ty_res, mk_res;
7979
export ty_param, mk_param;
80-
export ty_ptr, mk_ptr, mk_mut_ptr, type_is_unsafe_ptr;
80+
export ty_ptr, mk_ptr, mk_mut_ptr, mk_nil_ptr, type_is_unsafe_ptr;
8181
export ty_rptr, mk_rptr;
8282
export ty_rec, mk_rec;
8383
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)) }
482482
fn mk_mut_ptr(cx: ctxt, ty: t) -> t { mk_ptr(cx, {ty: ty,
483483
mutbl: ast::m_mutbl}) }
484484

485+
fn mk_nil_ptr(cx: ctxt) -> t {
486+
mk_ptr(cx, {ty: mk_nil(cx), mutbl: ast::m_imm})
487+
}
488+
485489
fn mk_vec(cx: ctxt, tm: mt) -> t { mk_t(cx, ty_vec(tm)) }
486490

487491
fn mk_rec(cx: ctxt, fs: [field]) -> t { mk_t(cx, ty_rec(fs)) }

0 commit comments

Comments
 (0)