Fix generic-bind support for bound aliases and generics.
This commit is contained in:
parent
da9ea9ab69
commit
01bfc3ae8b
4 changed files with 35 additions and 11 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
10
src/test/run-pass/generic-bind-2.rs
Normal file
10
src/test/run-pass/generic-bind-2.rs
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue