Skip to content

Commit f793309

Browse files
committed
---
yaml --- r: 1423 b: refs/heads/master c: b4d6589 h: refs/heads/master i: 1421: 3f10f53 1419: 7d5789d 1415: 4a628b3 1407: bb08404 v: v3
1 parent 5ae5743 commit f793309

File tree

4 files changed

+101
-20
lines changed

4 files changed

+101
-20
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: 381684043f1ad044c72347d759c1c545c6bccc3d
2+
refs/heads/master: b4d6589e7387a7c7df0841f51f0fa5ef831883d9

trunk/src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,7 @@ TEST_XFAILS_RUSTC := $(filter-out \
480480
foreach-simple.rs \
481481
fun-call-variants.rs \
482482
fun-indirect-call.rs \
483+
generic-bind.rs \
483484
generic-derived-type.rs \
484485
generic-fn.rs \
485486
generic-fn-infer.rs \

trunk/src/comp/middle/trans.rs

Lines changed: 96 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -373,11 +373,12 @@ fn T_typaram_ptr(type_names tn) -> TypeRef {
373373

374374
fn T_closure_ptr(type_names tn,
375375
TypeRef lltarget_ty,
376-
TypeRef llbindings_ty) -> TypeRef {
376+
TypeRef llbindings_ty,
377+
uint n_ty_params) -> TypeRef {
377378
ret T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc(tn)),
378379
lltarget_ty,
379-
llbindings_ty)
380-
// FIXME: add captured typarams.
380+
llbindings_ty,
381+
T_captured_tydescs(tn, n_ty_params))
381382
)));
382383
}
383384

@@ -388,7 +389,8 @@ fn T_opaque_closure_ptr(type_names tn) -> TypeRef {
388389
}
389390
auto t = T_closure_ptr(tn, T_struct(vec(T_ptr(T_nil()),
390391
T_ptr(T_nil()))),
391-
T_nil());
392+
T_nil(),
393+
0u);
392394
tn.associate(s, t);
393395
ret t;
394396
}
@@ -2747,17 +2749,15 @@ fn trans_bind_thunk(@crate_ctxt cx,
27472749
@ty.t outgoing_fty,
27482750
vec[option.t[@ast.expr]] args,
27492751
TypeRef llclosure_ty,
2750-
vec[@ty.t] bound_tys) -> ValueRef {
2752+
vec[@ty.t] bound_tys,
2753+
uint ty_param_count) -> ValueRef {
27512754
// Construct a thunk-call with signature incoming_fty, and that copies
27522755
// args forward into a call to outgoing_fty.
27532756

27542757
let str s = cx.names.next("_rust_thunk") + sep() + cx.path;
27552758
let TypeRef llthunk_ty = get_pair_fn_ty(type_of(cx, incoming_fty));
27562759
let ValueRef llthunk = decl_fastcall_fn(cx.llmod, s, llthunk_ty);
27572760

2758-
// FIXME: handle ty params properly.
2759-
let vec[ast.ty_param] ty_params = vec();
2760-
27612761
auto fcx = new_fn_ctxt(cx, s, llthunk);
27622762
auto bcx = new_top_block_ctxt(fcx);
27632763

@@ -2779,11 +2779,33 @@ fn trans_bind_thunk(@crate_ctxt cx,
27792779
vec(C_int(0),
27802780
C_int(abi.fn_field_box)));
27812781
lltargetclosure = bcx.build.Load(lltargetclosure);
2782-
let vec[ValueRef] llargs = vec(fcx.llretptr,
2782+
2783+
auto outgoing_ret_ty = ty.ty_fn_ret(outgoing_fty);
2784+
auto outgoing_arg_tys = ty.ty_fn_args(outgoing_fty);
2785+
2786+
auto llretptr = fcx.llretptr;
2787+
if (ty.type_has_dynamic_size(outgoing_ret_ty)) {
2788+
llretptr = bcx.build.PointerCast(llretptr, T_typaram_ptr(cx.tn));
2789+
}
2790+
2791+
let vec[ValueRef] llargs = vec(llretptr,
27832792
fcx.lltaskptr,
27842793
lltargetclosure);
2785-
let uint a = 0u;
2794+
2795+
// Copy in the type parameters.
2796+
let uint i = 0u;
2797+
while (i < ty_param_count) {
2798+
auto lltyparam_ptr =
2799+
bcx.build.GEP(llbody, vec(C_int(0),
2800+
C_int(abi.closure_elt_ty_params),
2801+
C_int(i as int)));
2802+
llargs += vec(bcx.build.Load(lltyparam_ptr));
2803+
i += 1u;
2804+
}
2805+
2806+
let uint a = 2u + i; // retptr, task ptr, env come first
27862807
let int b = 0;
2808+
let uint outgoing_arg_index = 0u;
27872809
for (option.t[@ast.expr] arg in args) {
27882810
alt (arg) {
27892811

@@ -2800,17 +2822,27 @@ fn trans_bind_thunk(@crate_ctxt cx,
28002822
// Arg will be provided when the thunk is invoked.
28012823
case (none[@ast.expr]) {
28022824
let ValueRef passed_arg = llvm.LLVMGetParam(llthunk, a);
2825+
if (ty.type_has_dynamic_size(outgoing_arg_tys.
2826+
(outgoing_arg_index).ty)) {
2827+
// Cast to a generic typaram pointer in order to make a
2828+
// type-compatible call.
2829+
passed_arg = bcx.build.PointerCast(passed_arg,
2830+
T_typaram_ptr(cx.tn));
2831+
}
28032832
llargs += passed_arg;
28042833
a += 1u;
28052834
}
28062835
}
2836+
2837+
outgoing_arg_index += 0u;
28072838
}
28082839

28092840
// FIXME: turn this call + ret into a tail call.
28102841
auto lltargetfn = bcx.build.GEP(lltarget,
28112842
vec(C_int(0),
28122843
C_int(abi.fn_field_code)));
28132844
lltargetfn = bcx.build.Load(lltargetfn);
2845+
28142846
auto r = bcx.build.FastCall(lltargetfn, llargs);
28152847
bcx.build.RetVoid();
28162848

@@ -2835,7 +2867,23 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
28352867
}
28362868
}
28372869
}
2838-
if (_vec.len[@ast.expr](bound) == 0u) {
2870+
2871+
// Figure out which tydescs we need to pass, if any.
2872+
// FIXME: typestate botch
2873+
let @ty.t outgoing_fty = ty.plain_ty(ty.ty_nil);
2874+
let vec[ValueRef] lltydescs = vec();
2875+
alt (f_res.generic) {
2876+
case (none[generic_info]) {
2877+
outgoing_fty = ty.expr_ty(f);
2878+
}
2879+
case (some[generic_info](?ginfo)) {
2880+
outgoing_fty = ginfo.item_type;
2881+
lltydescs = ginfo.tydescs;
2882+
}
2883+
}
2884+
auto ty_param_count = _vec.len[ValueRef](lltydescs);
2885+
2886+
if (_vec.len[@ast.expr](bound) == 0u && ty_param_count == 0u) {
28392887
// Trivial 'binding': just return the static pair-ptr.
28402888
ret f_res.res;
28412889
} else {
@@ -2846,20 +2894,27 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
28462894
// Translate the bound expressions.
28472895
let vec[@ty.t] bound_tys = vec();
28482896
let vec[ValueRef] bound_vals = vec();
2897+
auto i = 0u;
28492898
for (@ast.expr e in bound) {
28502899
auto arg = trans_expr(bcx, e);
28512900
bcx = arg.bcx;
2901+
28522902
append[ValueRef](bound_vals, arg.val);
28532903
append[@ty.t](bound_tys, ty.expr_ty(e));
2904+
2905+
i += 1u;
28542906
}
28552907

2908+
// Get the type of the bound function.
2909+
let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, outgoing_fty);
2910+
28562911
// Synthesize a closure type.
28572912
let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys));
2858-
let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, ty.expr_ty(f));
28592913
let TypeRef llbindings_ty = type_of(bcx.fcx.ccx, bindings_ty);
28602914
let TypeRef llclosure_ty = T_closure_ptr(cx.fcx.ccx.tn,
28612915
lltarget_ty,
2862-
llbindings_ty);
2916+
llbindings_ty,
2917+
ty_param_count);
28632918

28642919
// Malloc a box for the body.
28652920
auto r = trans_malloc_inner(bcx, llclosure_ty);
@@ -2888,19 +2943,40 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
28882943
bcx.build.GEP(closure,
28892944
vec(C_int(0),
28902945
C_int(abi.closure_elt_target)));
2891-
bcx.build.Store(bcx.build.Load(f_res.res.val), bound_target);
2946+
auto src = bcx.build.Load(f_res.res.val);
2947+
bcx.build.Store(src, bound_target);
28922948

28932949
// Copy expr values into boxed bindings.
2894-
let int i = 0;
2950+
i = 0u;
28952951
auto bindings =
28962952
bcx.build.GEP(closure,
28972953
vec(C_int(0),
28982954
C_int(abi.closure_elt_bindings)));
28992955
for (ValueRef v in bound_vals) {
29002956
auto bound = bcx.build.GEP(bindings,
2901-
vec(C_int(0),C_int(i)));
2957+
vec(C_int(0), C_int(i as int)));
29022958
bcx = copy_ty(r.bcx, INIT, bound, v, bound_tys.(i)).bcx;
2903-
i += 1;
2959+
i += 1u;
2960+
}
2961+
2962+
// If necessary, copy tydescs describing type parameters into the
2963+
// appropriate slot in the closure.
2964+
alt (f_res.generic) {
2965+
case (none[generic_info]) { /* nothing to do */ }
2966+
case (some[generic_info](?ginfo)) {
2967+
auto ty_params_slot =
2968+
bcx.build.GEP(closure,
2969+
vec(C_int(0),
2970+
C_int(abi.closure_elt_ty_params)));
2971+
auto i = 0;
2972+
for (ValueRef td in ginfo.tydescs) {
2973+
auto ty_param_slot = bcx.build.GEP(ty_params_slot,
2974+
vec(C_int(0),
2975+
C_int(i)));
2976+
bcx.build.Store(td, ty_param_slot);
2977+
i += 1;
2978+
}
2979+
}
29042980
}
29052981

29062982
// Make thunk and store thunk-ptr in outer pair's code slot.
@@ -2910,8 +2986,9 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
29102986

29112987
let @ty.t pair_ty = node_ann_type(cx.fcx.ccx, ann);
29122988
let ValueRef llthunk =
2913-
trans_bind_thunk(cx.fcx.ccx, pair_ty, ty.expr_ty(f),
2914-
args, llclosure_ty, bound_tys);
2989+
trans_bind_thunk(cx.fcx.ccx, pair_ty, outgoing_fty,
2990+
args, llclosure_ty, bound_tys,
2991+
ty_param_count);
29152992

29162993
bcx.build.Store(llthunk, pair_code);
29172994

trunk/src/comp/middle/ty.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,19 +598,22 @@ fn ty_fn_args(@t fty) -> vec[arg] {
598598
case (ty.ty_fn(_, ?a, _)) { ret a; }
599599
case (ty.ty_native_fn(?a, _)) { ret a; }
600600
}
601+
fail;
601602
}
602603

603604
fn ty_fn_proto(@t fty) -> ast.proto {
604605
alt (fty.struct) {
605606
case (ty.ty_fn(?p, _, _)) { ret p; }
606607
}
608+
fail;
607609
}
608610

609611
fn ty_fn_ret(@t fty) -> @t {
610612
alt (fty.struct) {
611613
case (ty.ty_fn(_, _, ?r)) { ret r; }
612614
case (ty.ty_native_fn(_, ?r)) { ret r; }
613615
}
616+
fail;
614617
}
615618

616619
fn is_fn_ty(@t fty) -> bool {

0 commit comments

Comments
 (0)