@@ -4411,10 +4411,12 @@ fn trans_bind_thunk(cx: &@local_ctxt, sp: &span, incoming_fty: &ty::t,
4411
4411
// "target", in this context, means the function that's having some of its
4412
4412
// arguments bound and that will be called inside the thunk we're
4413
4413
// 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.
4415
4416
let lltarget =
4416
4417
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 ] ) ;
4418
4420
bcx = lltarget. bcx ;
4419
4421
4420
4422
// 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,
4457
4459
4458
4460
let a: uint = 3 u; // retptr, task ptr, env come first
4459
4461
4460
- let b: int = 0 ;
4462
+ let b: int = 1 ;
4461
4463
let outgoing_arg_index: uint = 0 u;
4462
4464
let llout_arg_tys: TypeRef [ ] =
4463
4465
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,
4547
4549
}
4548
4550
4549
4551
// 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
4551
4554
let lltydescs: ValueRef [ ] ;
4552
4555
alt f_res. generic {
4553
- none. { outgoing_fty = ty :: expr_ty ( bcx_tcx ( cx ) , f ) ; lltydescs = ~[ ] ; }
4556
+ none. { outgoing_fty_real = outgoing_fty ; lltydescs = ~[ ] ; }
4554
4557
some ( ginfo) {
4555
4558
lazily_emit_all_generic_info_tydesc_glues ( cx, ginfo) ;
4556
- outgoing_fty = ginfo. item_type ;
4559
+ outgoing_fty_real = ginfo. item_type ;
4557
4560
lltydescs = ginfo. tydescs ;
4558
4561
}
4559
4562
}
@@ -4565,9 +4568,17 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
4565
4568
}
4566
4569
let bcx = f_res. res . bcx ;
4567
4570
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] ;
4568
4581
// Translate the bound expressions.
4569
- let bound_tys: ty:: t [ ] = ~[ ] ;
4570
- let bound_vals: lval_result [ ] = ~[ ] ;
4571
4582
for e: @ast:: expr in bound {
4572
4583
let lv = trans_lval ( bcx, e) ;
4573
4584
bcx = lv. res . bcx ;
@@ -4627,14 +4638,6 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
4627
4638
bcx = bindings_tydesc. bcx ;
4628
4639
bcx. build . Store ( bindings_tydesc. val , bound_tydesc) ;
4629
4640
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
-
4638
4641
// Copy expr values into boxed bindings.
4639
4642
let i = 0 u;
4640
4643
let bindings =
@@ -4647,28 +4650,24 @@ fn trans_bind_1(cx: &@block_ctxt, f: &@ast::expr, f_res: &lval_result,
4647
4650
4648
4651
// If necessary, copy tydescs describing type parameters into the
4649
4652
// appropriate slot in the closure.
4650
- alt f_res. generic {
4651
- none. { /* nothing to do */ }
4652
- some ( ginfo) {
4653
+ if ty_param_count > 0 u {
4653
4654
let ty_params_slot =
4654
4655
bcx. build . GEP ( closure,
4655
4656
~[ C_int ( 0 ) , C_int ( abi:: closure_elt_ty_params) ] ) ;
4656
4657
let i = 0 ;
4657
- for td: ValueRef in ginfo . tydescs {
4658
+ for td: ValueRef in lltydescs {
4658
4659
let ty_param_slot =
4659
4660
bcx. build . GEP ( ty_params_slot, ~[ C_int ( 0 ) , C_int ( i) ] ) ;
4660
4661
bcx. build . Store ( td, ty_param_slot) ;
4661
4662
i += 1 ;
4662
4663
}
4663
- outgoing_fty = ginfo. item_type ;
4664
- }
4665
4664
}
4666
4665
4667
4666
// Make thunk
4668
4667
// The type of the entire bind expression.
4669
4668
let pair_ty = node_id_type ( bcx_ccx ( cx) , id) ;
4670
4669
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 ,
4672
4671
args, closure_ty, bound_tys, ty_param_count) ;
4673
4672
4674
4673
// Construct the function pair
0 commit comments