diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Makefile | 1 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 32 | ||||
| -rw-r--r-- | src/test/run-pass/generic-bind-2.rs | 10 | ||||
| -rw-r--r-- | src/test/run-pass/generic-bind.rs | 3 |
4 files changed, 35 insertions, 11 deletions
diff --git a/src/Makefile b/src/Makefile index 2729fc78..1572764d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -409,6 +409,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/run-pass/obj-as.rs \ test/run-pass/vec-slice.rs \ test/run-pass/fn-lval.rs \ + test/run-pass/generic-bind-2.rs \ test/run-pass/generic-fn-box.rs \ test/run-pass/generic-tup.rs \ test/run-pass/iter-ret.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4064cc0a..5b2e12a6 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3364,7 +3364,7 @@ fn trans_bind_thunk(@crate_ctxt cx, lltargetclosure = bcx.build.Load(lltargetclosure); auto outgoing_ret_ty = ty.ty_fn_ret(outgoing_fty); - auto outgoing_arg_tys = ty.ty_fn_args(outgoing_fty); + auto outgoing_args = ty.ty_fn_args(outgoing_fty); auto llretptr = fcx.llretptr; if (ty.type_has_dynamic_size(outgoing_ret_ty)) { @@ -3392,7 +3392,14 @@ fn trans_bind_thunk(@crate_ctxt cx, let uint a = 2u + i; // retptr, task ptr, env come first let int b = 0; let uint outgoing_arg_index = 0u; + let vec[TypeRef] llout_arg_tys = + type_of_explicit_args(cx, outgoing_args); + for (option.t[@ast.expr] arg in args) { + + auto out_arg = outgoing_args.(outgoing_arg_index); + auto llout_arg_ty = llout_arg_tys.(outgoing_arg_index); + alt (arg) { // Arg provided at binding time; thunk copies it from closure. @@ -3403,22 +3410,31 @@ fn trans_bind_thunk(@crate_ctxt cx, abi.box_rc_field_body, abi.closure_elt_bindings, b)); - // FIXME: possibly support passing aliases someday. + bcx = bound_arg.bcx; - llargs += bcx.build.Load(bound_arg.val); + auto val = bound_arg.val; + + if (out_arg.mode == ast.val) { + val = bcx.build.Load(val); + } else if (ty.count_ty_params(out_arg.ty) > 0u) { + check (out_arg.mode == ast.alias); + val = bcx.build.PointerCast(val, llout_arg_ty); + } + + llargs += val; b += 1; } // Arg will be provided when the thunk is invoked. case (none[@ast.expr]) { let ValueRef passed_arg = llvm.LLVMGetParam(llthunk, a); - if (ty.type_has_dynamic_size(outgoing_arg_tys. - (outgoing_arg_index).ty)) { - // Cast to a generic typaram pointer in order to make a - // type-compatible call. + + if (ty.count_ty_params(out_arg.ty) > 0u) { + check (out_arg.mode == ast.alias); passed_arg = bcx.build.PointerCast(passed_arg, - T_typaram_ptr(cx.tn)); + llout_arg_ty); } + llargs += passed_arg; a += 1u; } diff --git a/src/test/run-pass/generic-bind-2.rs b/src/test/run-pass/generic-bind-2.rs new file mode 100644 index 00000000..95a8cab4 --- /dev/null +++ b/src/test/run-pass/generic-bind-2.rs @@ -0,0 +1,10 @@ +fn id[T](&T t) -> T { + ret t; +} + +fn main() { + auto t = tup(1,2,3,4,5,6,7); + check (t._5 == 6); + auto f0 = bind id[tup(int,int,int,int,int,int,int)](t); + check (f0()._5 == 6); +} diff --git a/src/test/run-pass/generic-bind.rs b/src/test/run-pass/generic-bind.rs index 5f44bcee..ef1275e3 100644 --- a/src/test/run-pass/generic-bind.rs +++ b/src/test/run-pass/generic-bind.rs @@ -5,9 +5,6 @@ fn id[T](&T t) -> T { fn main() { auto t = tup(1,2,3,4,5,6,7); check (t._5 == 6); - // FIXME: this needs to work. - // auto f0 = bind id[tup(int,int,int,int,int,int,int)](t); auto f1 = bind id[tup(int,int,int,int,int,int,int)](_); - // check (f0()._5 == 6); check (f1(t)._5 == 6); } |