Skip to content

Commit c817500

Browse files
committed
---
yaml --- r: 4190 b: refs/heads/master c: b977b5c h: refs/heads/master v: v3
1 parent f7599f4 commit c817500

File tree

2 files changed

+23
-24
lines changed

2 files changed

+23
-24
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: db1923159692818becfc0fe386f19cb0f6151855
2+
refs/heads/master: b977b5c508bc34fea27a2bfa4b637ab6df8ad7f4

trunk/src/comp/middle/trans.rs

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4411,10 +4411,12 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
44114411
// "target", in this context, means the function that's having some of its
44124412
// arguments bound and that will be called inside the thunk we're
44134413
// creating. (In our running example, target is the function f.) Pick
4414-
// out the pointer to the target function from the environment.
4414+
// out the pointer to the target function from the environment. The
4415+
// target function lives in the first binding spot.
44154416
let lltarget =
44164417
GEP_tup_like(bcx, closure_ty, llclosure,
4417-
~[0, abi::box_rc_field_body, abi::closure_elt_target]);
4418+
~[0, abi::box_rc_field_body,
4419+
abi::closure_elt_bindings, 0]);
44184420
bcx = lltarget.bcx;
44194421

44204422
// And then, pick out the target function's own environment. That's what
@@ -4457,7 +4459,7 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
44574459

44584460
let a: uint = 3u; // retptr, task ptr, env come first
44594461

4460-
let b: int = 0;
4462+
let b: int = 1;
44614463
let outgoing_arg_index: uint = 0u;
44624464
let llout_arg_tys: TypeRef[] =
44634465
type_of_explicit_args(cx.ccx, sp, outgoing_args);
@@ -4547,13 +4549,14 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
45474549
}
45484550

45494551
// Figure out which tydescs we need to pass, if any.
4550-
let outgoing_fty: ty::t;
4552+
let outgoing_fty: ty::t = ty::expr_ty(bcx_tcx(cx), f);
4553+
let outgoing_fty_real; // the type with typarams still in it
45514554
let lltydescs: ValueRef[];
45524555
alt f_res.generic {
4553-
none. { outgoing_fty = ty::expr_ty(bcx_tcx(cx), f); lltydescs = ~[]; }
4556+
none. { outgoing_fty_real = outgoing_fty; lltydescs = ~[]; }
45544557
some(ginfo) {
45554558
lazily_emit_all_generic_info_tydesc_glues(cx, ginfo);
4556-
outgoing_fty = ginfo.item_type;
4559+
outgoing_fty_real = ginfo.item_type;
45574560
lltydescs = ginfo.tydescs;
45584561
}
45594562
}
@@ -4565,9 +4568,17 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
45654568
}
45664569
let bcx = f_res.res.bcx;
45674570

4571+
// Cast the function we are binding to be the type that the closure
4572+
// will expect it to have. The type the closure knows about has the
4573+
// type parameters substituted with the real types.
4574+
let llclosurety = T_ptr(type_of(bcx_ccx(cx), cx.sp, outgoing_fty));
4575+
let src_loc = bcx.build.PointerCast(f_res.res.val, llclosurety);
4576+
let bound_f = {res: {bcx: bcx, val: src_loc} with f_res};
4577+
4578+
// Arrange for the bound function to live in the first binding spot.
4579+
let bound_tys: ty::t[] = ~[outgoing_fty];
4580+
let bound_vals: lval_result[] = ~[bound_f];
45684581
// Translate the bound expressions.
4569-
let bound_tys: ty::t[] = ~[];
4570-
let bound_vals: lval_result[] = ~[];
45714582
for e: @ast::expr in bound {
45724583
let lv = trans_lval(bcx, e);
45734584
bcx = lv.res.bcx;
@@ -4627,14 +4638,6 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
46274638
bcx = bindings_tydesc.bcx;
46284639
bcx.build.Store(bindings_tydesc.val, bound_tydesc);
46294640

4630-
// Store thunk-target.
4631-
let bound_target =
4632-
bcx.build.GEP(closure, ~[C_int(0), C_int(abi::closure_elt_target)]);
4633-
let llclosurety = T_ptr(type_of(bcx_ccx(cx), cx.sp, outgoing_fty));
4634-
let src_loc = bcx.build.PointerCast(f_res.res.val, llclosurety);
4635-
let src = bcx.build.Load(src_loc);
4636-
bcx.build.Store(src, bound_target);
4637-
46384641
// Copy expr values into boxed bindings.
46394642
let i = 0u;
46404643
let bindings =
@@ -4647,28 +4650,24 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
46474650

46484651
// If necessary, copy tydescs describing type parameters into the
46494652
// appropriate slot in the closure.
4650-
alt f_res.generic {
4651-
none. {/* nothing to do */ }
4652-
some(ginfo) {
4653+
if ty_param_count > 0u {
46534654
let ty_params_slot =
46544655
bcx.build.GEP(closure,
46554656
~[C_int(0), C_int(abi::closure_elt_ty_params)]);
46564657
let i = 0;
4657-
for td: ValueRef in ginfo.tydescs {
4658+
for td: ValueRef in lltydescs {
46584659
let ty_param_slot =
46594660
bcx.build.GEP(ty_params_slot, ~[C_int(0), C_int(i)]);
46604661
bcx.build.Store(td, ty_param_slot);
46614662
i += 1;
46624663
}
4663-
outgoing_fty = ginfo.item_type;
4664-
}
46654664
}
46664665

46674666
// Make thunk
46684667
// The type of the entire bind expression.
46694668
let pair_ty = node_id_type(bcx_ccx(cx), id);
46704669
let llthunk =
4671-
trans_bind_thunk(cx.fcx.lcx, cx.sp, pair_ty, outgoing_fty,
4670+
trans_bind_thunk(cx.fcx.lcx, cx.sp, pair_ty, outgoing_fty_real,
46724671
args, closure_ty, bound_tys, ty_param_count);
46734672

46744673
// Construct the function pair

0 commit comments

Comments
 (0)