Skip to content

Commit 58e67c2

Browse files
committed
Make bare functions a single non-immediate pointer
It's pretty ugly still because there's some dissonance between the 1-word and 2-word function types Issue rust-lang#1022
1 parent 5dd2294 commit 58e67c2

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

src/comp/middle/trans.rs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,18 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
205205
}
206206
T_struct(tys)
207207
}
208-
ty::ty_fn(_, _, _, _, _) {
208+
ty::ty_fn(proto, _, _, _, _) {
209209
// FIXME: could be a constraint on ty_fn
210210
check returns_non_ty_var(cx, t);
211-
T_fn_pair(*cx, type_of_fn_from_ty(cx, sp, t, 0u))
211+
let llfnty = type_of_fn_from_ty(cx, sp, t, 0u);
212+
alt proto {
213+
ast::proto_bare. {
214+
T_ptr(llfnty)
215+
}
216+
_ {
217+
T_fn_pair(*cx, llfnty)
218+
}
219+
}
212220
}
213221
ty::ty_native_fn(abi, args, out) {
214222
if native_abi_requires_pair(abi) {
@@ -1429,9 +1437,15 @@ fn make_drop_glue(bcx: @block_ctxt, v0: ValueRef, t: ty::t) {
14291437
ty::ty_res(did, inner, tps) {
14301438
trans_res_drop(bcx, v0, did, inner, tps)
14311439
}
1432-
ty::ty_fn(_, _, _, _, _) {
1433-
let box_cell = GEP(bcx, v0, [C_int(0), C_int(abi::fn_field_box)]);
1434-
decr_refcnt_maybe_free(bcx, Load(bcx, box_cell), t)
1440+
ty::ty_fn(proto, _, _, _, _) {
1441+
alt proto {
1442+
ast::proto_bare. { bcx }
1443+
_ {
1444+
let box_cell = GEP(bcx, v0, [C_int(0),
1445+
C_int(abi::fn_field_box)]);
1446+
decr_refcnt_maybe_free(bcx, Load(bcx, box_cell), t)
1447+
}
1448+
}
14351449
}
14361450
_ {
14371451
if ty::type_has_pointers(ccx.tcx, t) &&
@@ -1754,6 +1768,7 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
17541768
}
17551769
ret next_cx;
17561770
}
1771+
ty::ty_fn(ast::proto_bare., _, _, _, _) { ret cx; }
17571772
ty::ty_fn(_, _, _, _, _) | ty::ty_native_fn(_, _, _) {
17581773
let box_cell_a = GEP(cx, av, [C_int(0), C_int(abi::fn_field_box)]);
17591774
ret iter_boxpp(cx, box_cell_a, f);
@@ -2297,7 +2312,14 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span,
22972312
trans_closure(sub_cx, sp, f, llfn, none, [], id, {|_fcx|});
22982313
}
22992314
};
2300-
fill_fn_pair(bcx, get_dest_addr(dest), llfn, env);
2315+
alt f.proto {
2316+
ast::proto_bare. {
2317+
Store(bcx, llfn, get_dest_addr(dest));
2318+
}
2319+
_ {
2320+
fill_fn_pair(bcx, get_dest_addr(dest), llfn, env);
2321+
}
2322+
}
23012323
ret bcx;
23022324
}
23032325

@@ -2987,7 +3009,7 @@ type generic_info =
29873009

29883010
tag lval_kind { temporary; owned; owned_imm; }
29893011
type lval_result = {bcx: @block_ctxt, val: ValueRef, kind: lval_kind};
2990-
tag callee_env { obj_env(ValueRef); null_env; is_closure; }
3012+
tag callee_env { obj_env(ValueRef); null_env; no_env; is_closure; }
29913013
type lval_maybe_callee = {bcx: @block_ctxt,
29923014
val: ValueRef,
29933015
kind: lval_kind,
@@ -3147,7 +3169,16 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
31473169
}
31483170
_ {
31493171
let loc = trans_local_var(cx, def);
3150-
ret lval_no_env(loc.bcx, loc.val, loc.kind);
3172+
let tp = ty::node_id_to_monotype(ccx.tcx, id);
3173+
alt ty::struct(ccx.tcx, tp) {
3174+
ty::ty_fn(ast::proto_bare.,_,_,_,_) {
3175+
ret {bcx: loc.bcx, val: loc.val,
3176+
kind: loc.kind, env: no_env, generic: none};
3177+
}
3178+
_ {
3179+
ret lval_no_env(loc.bcx, loc.val, loc.kind);
3180+
}
3181+
}
31513182
}
31523183
}
31533184
}
@@ -3346,6 +3377,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
33463377
fn maybe_add_env(bcx: @block_ctxt, c: lval_maybe_callee)
33473378
-> (lval_kind, ValueRef) {
33483379
alt c.env {
3380+
no_env. { (c.kind, c.val) }
33493381
is_closure. { (c.kind, c.val) }
33503382
obj_env(_) {
33513383
fail "Taking the value of a method does not work yet (issue #435)";
@@ -3937,6 +3969,11 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
39373969
null_env. {
39383970
llenv = llvm::LLVMGetUndef(T_opaque_closure_ptr(*bcx_ccx(cx)));
39393971
}
3972+
no_env. {
3973+
// Bare functions. They still aren't immediates so need to be loaded
3974+
faddr = Load(bcx, faddr);
3975+
llenv = llvm::LLVMGetUndef(T_opaque_closure_ptr(*bcx_ccx(cx)));
3976+
}
39403977
obj_env(e) { llenv = e; }
39413978
is_closure. {
39423979
// It's a closure. Have to fetch the elements

src/test/run-pass/fn-bare-anon-2.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
let f: fn#() = fn# () {
3+
log "This is a bare function"
4+
};
5+
let g;
6+
g = f;
7+
}

0 commit comments

Comments
 (0)