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; 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)]); let box_cell_a = GEP(cx, av, [C_int(0), C_int(abi::fn_field_box)]);
ret iter_boxpp(cx, box_cell_a, f); 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 { lval_result {
let ccx = bcx_ccx(cx); let ccx = bcx_ccx(cx);
alt def { alt def {
ast::def_fn(did, _) { ast::def_fn(did, _) | ast::def_native_fn(did) {
let tyt = ty::lookup_item_type(ccx.tcx, did); let tyt = ty::lookup_item_type(ccx.tcx, did);
ret lval_generic_fn(cx, tyt, did, id); 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)); 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); } _ { 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; rptr = result.rptr;
} }
_ { _ {
r = r = trans_native_call(new_raw_block_ctxt(bcx.fcx, bcx.llbb),
trans_native_call(new_raw_block_ctxt(bcx.fcx, bcx.llbb),
ccx.externs, ccx.llmod, name, call_args); ccx.externs, ccx.llmod, name, call_args);
rptr = BitCast(bcx, fcx.llretptr, T_ptr(T_i32())); 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_tup(_) { ret true; }
ty_tag(_, _) { ret true; } ty_tag(_, _) { ret true; }
ty_fn(_, _, _, _, _) { ret true; } ty_fn(_, _, _, _, _) { ret true; }
ty_native_fn(_, _, _) { ret true; }
ty_obj(_) { ret true; } ty_obj(_) { ret true; }
ty_res(_, _, _) { ret true; } ty_res(_, _, _) { ret true; }
_ { ret false; } _ { 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); bot = check_call_or_bind(fcx, expr.span, f, args, kind_bind);
// Pull the argument and return types out. // Pull the argument and return types out.
let proto_1; let (proto, arg_tys, rt, cf, constrs) =
let arg_tys_1: [ty::arg] = []; alt structure_of(fcx, expr.span, expr_ty(tcx, f)) {
let rt_1; // FIXME:
let fty = expr_ty(tcx, f); // probably need to munge the constrs to drop constraints
let t_1; // for any bound args
alt structure_of(fcx, expr.span, fty) { ty::ty_fn(proto, arg_tys, rt, cf, constrs) {
ty::ty_fn(proto, arg_tys, rt, cf, constrs) { (proto, arg_tys, rt, cf, constrs)
proto_1 = proto; }
rt_1 = rt; ty::ty_native_fn(_, arg_tys, rt) {
// FIXME: (ast::proto_fn, arg_tys, rt, ast::return, [])
// probably need to munge the constrs to drop constraints }
// for any bound args _ { fail "LHS of bind expr didn't have a function type?!"; }
};
// For each blank argument, add the type of that argument // For each blank argument, add the type of that argument
// to the resulting function type. // to the resulting function type.
let i = 0u; let out_args = [];
while i < vec::len::<option::t<@ast::expr>>(args) { let i = 0u;
alt args[i] { while i < vec::len(args) {
some(_) {/* no-op */ } alt args[i] {
none. { arg_tys_1 += [arg_tys[i]]; } some(_) {/* no-op */ }
} none. { out_args += [arg_tys[i]]; }
i += 1u;
} }
t_1 = ty::mk_fn(tcx, proto_1, arg_tys_1, rt_1, cf, constrs); i += 1u;
}
_ { fail "LHS of bind expr didn't have a function type?!"; }
} }
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) { ast::expr_call(f, args) {
bot = check_call_full(fcx, expr.span, f, args, kind_call, expr.id); bot = check_call_full(fcx, expr.span, f, args, kind_call, expr.id);