@@ -3351,8 +3351,7 @@ fn trans_bind_thunk(cx: @local_ctxt, sp: span, incoming_fty: ty::t,
3351
3351
// out the pointer to the target function from the environment. The
3352
3352
// target function lives in the first binding spot.
3353
3353
let ( lltargetfn, lltargetenv, starting_idx) = alt target_fn {
3354
- some( fptr) { ( fptr, null_env_ptr ( bcx) , 0 )
3355
- }
3354
+ some( fptr) { ( fptr, llvm:: LLVMGetUndef ( T_opaque_closure_ptr ( * ccx) ) , 0 ) }
3356
3355
none. {
3357
3356
// Silly check
3358
3357
check type_is_tup_like ( bcx, closure_ty) ;
@@ -3646,12 +3645,7 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
3646
3645
to_zero : to_zero,
3647
3646
to_revoke : to_revoke} ;
3648
3647
}
3649
- let retty = ty:: ty_fn_ret ( tcx, fn_ty) ;
3650
- let llretslot_res = if by_ref {
3651
- rslt ( cx, alloca ( cx, T_ptr ( type_of_or_i8 ( bcx, retty) ) ) )
3652
- } else { alloc_ty ( bcx, retty) } ;
3653
- bcx = llretslot_res. bcx ;
3654
- let llretslot = llretslot_res. val ;
3648
+ let retty = ty:: ty_fn_ret ( tcx, fn_ty) , full_retty = retty;
3655
3649
alt gen {
3656
3650
some ( g) {
3657
3651
lazily_emit_all_generic_info_tydesc_glues ( cx, g) ;
@@ -3661,6 +3655,13 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef,
3661
3655
}
3662
3656
_ { }
3663
3657
}
3658
+ let llretslot_res = if ty:: type_is_nil ( tcx, retty) {
3659
+ rslt ( cx, llvm:: LLVMGetUndef ( T_ptr ( T_nil ( ) ) ) )
3660
+ } else if by_ref {
3661
+ rslt ( cx, alloca ( cx, T_ptr ( type_of_or_i8 ( bcx, full_retty) ) ) )
3662
+ } else { alloc_ty ( bcx, full_retty) } ;
3663
+ bcx = llretslot_res. bcx ;
3664
+ let llretslot = llretslot_res. val ;
3664
3665
if ty:: type_contains_params ( tcx, retty) {
3665
3666
// It's possible that the callee has some generic-ness somewhere in
3666
3667
// its return value -- say a method signature within an obj or a fn
@@ -3744,7 +3745,9 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr,
3744
3745
let faddr = f_res. val ;
3745
3746
let llenv;
3746
3747
alt f_res. env {
3747
- null_env. { llenv = null_env_ptr ( cx) ; }
3748
+ null_env. {
3749
+ llenv = llvm:: LLVMGetUndef ( T_opaque_closure_ptr ( * bcx_ccx ( cx) ) ) ;
3750
+ }
3748
3751
some_env ( e) { llenv = e; }
3749
3752
is_closure. {
3750
3753
// It's a closure. Have to fetch the elements
@@ -4570,7 +4573,9 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result {
4570
4573
let t = ty:: expr_ty ( bcx_tcx ( cx) , x) ;
4571
4574
let lv = trans_lval ( cx, x) ;
4572
4575
bcx = lv. bcx ;
4573
- if ast_util:: ret_by_ref ( cx. fcx . ret_style ) {
4576
+ if ty:: type_is_nil ( bcx_tcx ( cx) , t) {
4577
+ // Don't write nil
4578
+ } else if ast_util:: ret_by_ref ( cx. fcx . ret_style ) {
4574
4579
assert lv. is_mem ;
4575
4580
Store ( bcx, lv. val , cx. fcx . llretptr ) ;
4576
4581
} else {
@@ -4590,10 +4595,7 @@ fn trans_ret(cx: @block_ctxt, e: option::t<@ast::expr>) -> result {
4590
4595
}
4591
4596
}
4592
4597
}
4593
- _ {
4594
- let t = llvm:: LLVMGetElementType ( val_ty ( cx. fcx . llretptr ) ) ;
4595
- Store ( bcx, C_null ( t) , cx. fcx . llretptr ) ;
4596
- }
4598
+ _ { }
4597
4599
}
4598
4600
// run all cleanups and back out.
4599
4601
@@ -5280,7 +5282,8 @@ fn trans_closure(bcx_maybe: option::t<@block_ctxt>,
5280
5282
// (trans_block, trans_expr, et cetera).
5281
5283
let rslt =
5282
5284
if !ty:: type_is_bot ( cx. ccx . tcx , block_ty) &&
5283
- f. proto != ast:: proto_iter {
5285
+ !ty:: type_is_nil ( cx. ccx . tcx , block_ty) &&
5286
+ f. proto != ast:: proto_iter {
5284
5287
trans_block ( bcx, f. body , save_in ( fcx. llretptr ) )
5285
5288
} else { trans_block ( bcx, f. body , return ) } ;
5286
5289
bcx = rslt. bcx ;
0 commit comments