@@ -205,10 +205,18 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t)
205
205
}
206
206
T_struct ( tys)
207
207
}
208
- ty:: ty_fn ( _ , _, _, _, _) {
208
+ ty:: ty_fn ( proto , _, _, _, _) {
209
209
// FIXME: could be a constraint on ty_fn
210
210
check returns_non_ty_var ( cx, t) ;
211
- T_fn_pair ( * cx, type_of_fn_from_ty ( cx, sp, t, 0 u) )
211
+ let llfnty = type_of_fn_from_ty ( cx, sp, t, 0 u) ;
212
+ alt proto {
213
+ ast : : proto_bare. {
214
+ T_ptr ( llfnty)
215
+ }
216
+ _ {
217
+ T_fn_pair ( * cx, llfnty)
218
+ }
219
+ }
212
220
}
213
221
ty:: ty_native_fn ( abi, args, out) {
214
222
if native_abi_requires_pair ( abi) {
@@ -1429,9 +1437,15 @@ fn make_drop_glue(bcx: @block_ctxt, v0: ValueRef, t: ty::t) {
1429
1437
ty:: ty_res ( did, inner, tps) {
1430
1438
trans_res_drop ( bcx, v0, did, inner, tps)
1431
1439
}
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
+ }
1435
1449
}
1436
1450
_ {
1437
1451
if ty:: type_has_pointers ( ccx. tcx , t) &&
@@ -1754,6 +1768,7 @@ fn iter_structural_ty(cx: @block_ctxt, av: ValueRef, t: ty::t,
1754
1768
}
1755
1769
ret next_cx;
1756
1770
}
1771
+ ty:: ty_fn ( ast:: proto_bare. , _, _, _, _) { ret cx; }
1757
1772
ty:: ty_fn ( _, _, _, _, _) | ty:: ty_native_fn ( _, _, _) {
1758
1773
let box_cell_a = GEP ( cx, av, [ C_int ( 0 ) , C_int ( abi:: fn_field_box) ] ) ;
1759
1774
ret iter_boxpp( cx, box_cell_a, f) ;
@@ -2297,7 +2312,14 @@ fn trans_expr_fn(bcx: @block_ctxt, f: ast::_fn, sp: span,
2297
2312
trans_closure ( sub_cx, sp, f, llfn, none, [ ] , id, { |_fcx|} ) ;
2298
2313
}
2299
2314
} ;
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
+ }
2301
2323
ret bcx;
2302
2324
}
2303
2325
@@ -2987,7 +3009,7 @@ type generic_info =
2987
3009
2988
3010
tag lval_kind { temporary; owned; owned_imm; }
2989
3011
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; }
2991
3013
type lval_maybe_callee = { bcx: @block_ctxt,
2992
3014
val: ValueRef ,
2993
3015
kind: lval_kind,
@@ -3147,7 +3169,16 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
3147
3169
}
3148
3170
_ {
3149
3171
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
+ }
3151
3182
}
3152
3183
}
3153
3184
}
@@ -3346,6 +3377,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
3346
3377
fn maybe_add_env ( bcx : @block_ctxt , c : lval_maybe_callee )
3347
3378
-> ( lval_kind , ValueRef ) {
3348
3379
alt c. env {
3380
+ no_env. { ( c. kind , c. val ) }
3349
3381
is_closure. { ( c. kind , c. val ) }
3350
3382
obj_env ( _) {
3351
3383
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,
3937
3969
null_env. {
3938
3970
llenv = llvm:: LLVMGetUndef ( T_opaque_closure_ptr ( * bcx_ccx ( cx) ) ) ;
3939
3971
}
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
+ }
3940
3977
obj_env ( e) { llenv = e; }
3941
3978
is_closure. {
3942
3979
// It's a closure. Have to fetch the elements
0 commit comments