Make it possible to take the value of (and bind) native fns

Closes #820
This commit is contained in:
Marijn Haverbeke 2011-09-07 12:12:20 +02:00
parent 8ab02f7b21
commit f3edf8dd5e
3 changed files with 28 additions and 33 deletions

View file

@ -1737,7 +1737,7 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
}
ret next_cx;
}
ty::ty_fn(_, _, _, _, _) {
ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _, _) {
let box_cell_a = GEP(cx, av, [C_int(0), C_int(abi::fn_field_box)]);
ret iter_boxpp(cx, box_cell_a, f);
}
@ -3047,7 +3047,7 @@ fn trans_var(cx: &@block_ctxt, sp: &span, def: &ast::def, id: ast::node_id) ->
lval_result {
let ccx = bcx_ccx(cx);
alt def {
ast::def_fn(did, _) {
ast::def_fn(did, _) | ast::def_native_fn(did) {
let tyt = ty::lookup_item_type(ccx.tcx, did);
ret lval_generic_fn(cx, tyt, did, id);
}
@ -3092,10 +3092,6 @@ fn trans_var(cx: &@block_ctxt, sp: &span, def: &ast::def, id: ast::node_id) ->
tp));
}
}
ast::def_native_fn(did) {
let tyt = ty::lookup_item_type(ccx.tcx, did);
ret lval_generic_fn(cx, tyt, did, id);
}
_ { ret trans_local_var(cx, def); }
}
}
@ -5743,8 +5739,7 @@ fn decl_native_fn_and_pair(ccx: &@crate_ctxt, sp: &span, path: &[str],
rptr = result.rptr;
}
_ {
r =
trans_native_call(new_raw_block_ctxt(bcx.fcx, bcx.llbb),
r = trans_native_call(new_raw_block_ctxt(bcx.fcx, bcx.llbb),
ccx.externs, ccx.llmod, name, call_args);
rptr = BitCast(bcx, fcx.llretptr, T_ptr(T_i32()));
}

View file

@ -801,6 +801,7 @@ fn type_is_structural(cx: &ctxt, ty: t) -> bool {
ty_tup(_) { ret true; }
ty_tag(_, _) { ret true; }
ty_fn(_, _, _, _, _) { ret true; }
ty_native_fn(_, _, _) { ret true; }
ty_obj(_) { ret true; }
ty_res(_, _, _) { ret true; }
_ { ret false; }

View file

@ -2055,34 +2055,33 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr, unify: &unifier,
bot = check_call_or_bind(fcx, expr.span, f, args, kind_bind);
// Pull the argument and return types out.
let proto_1;
let arg_tys_1: [ty::arg] = [];
let rt_1;
let fty = expr_ty(tcx, f);
let t_1;
alt structure_of(fcx, expr.span, fty) {
ty::ty_fn(proto, arg_tys, rt, cf, constrs) {
proto_1 = proto;
rt_1 = rt;
// FIXME:
// probably need to munge the constrs to drop constraints
// for any bound args
let (proto, arg_tys, rt, cf, constrs) =
alt structure_of(fcx, expr.span, expr_ty(tcx, f)) {
// FIXME:
// probably need to munge the constrs to drop constraints
// for any bound args
ty::ty_fn(proto, arg_tys, rt, cf, constrs) {
(proto, arg_tys, rt, cf, constrs)
}
ty::ty_native_fn(_, arg_tys, rt) {
(ast::proto_fn, arg_tys, rt, ast::return, [])
}
_ { fail "LHS of bind expr didn't have a function type?!"; }
};
// For each blank argument, add the type of that argument
// to the resulting function type.
let i = 0u;
while i < vec::len::<option::t<@ast::expr>>(args) {
alt args[i] {
some(_) {/* no-op */ }
none. { arg_tys_1 += [arg_tys[i]]; }
}
i += 1u;
// For each blank argument, add the type of that argument
// to the resulting function type.
let out_args = [];
let i = 0u;
while i < vec::len(args) {
alt args[i] {
some(_) {/* no-op */ }
none. { out_args += [arg_tys[i]]; }
}
t_1 = ty::mk_fn(tcx, proto_1, arg_tys_1, rt_1, cf, constrs);
}
_ { fail "LHS of bind expr didn't have a function type?!"; }
i += 1u;
}
write::ty_only_fixup(fcx, id, t_1);
let ft = ty::mk_fn(tcx, proto, out_args, rt, cf, constrs);
write::ty_only_fixup(fcx, id, ft);
}
ast::expr_call(f, args) {
bot = check_call_full(fcx, expr.span, f, args, kind_call, expr.id);