Skip to content

Commit 5e7657f

Browse files
committed
Distinguish zero-size types from those that we return as void
1 parent 76c9028 commit 5e7657f

File tree

8 files changed

+34
-20
lines changed

8 files changed

+34
-20
lines changed

src/librustc/middle/trans/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,7 +1320,7 @@ pub fn init_function<'a>(
13201320
}
13211321
};
13221322

1323-
if !type_is_voidish(fcx.ccx, substd_output_type) {
1323+
if !return_type_is_void(fcx.ccx, substd_output_type) {
13241324
// If the function returns nil/bot, there is no real return
13251325
// value, so do not set `llretptr`.
13261326
if !skip_retptr || fcx.caller_expects_out_pointer {
@@ -1539,7 +1539,7 @@ pub fn trans_closure(ccx: @CrateContext,
15391539
// translation calls that don't have a return value (trans_crate,
15401540
// trans_mod, trans_item, et cetera) and those that do
15411541
// (trans_block, trans_expr, et cetera).
1542-
if body.expr.is_none() || type_is_voidish(bcx.ccx(), block_ty) {
1542+
if body.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
15431543
bcx = controlflow::trans_block(bcx, body, expr::Ignore);
15441544
} else {
15451545
let dest = expr::SaveIn(fcx.llretptr.get().unwrap());
@@ -1679,7 +1679,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
16791679

16801680
let bcx = fcx.entry_bcx.get().unwrap();
16811681

1682-
if !type_is_voidish(fcx.ccx, result_ty) {
1682+
if !type_is_zero_size(fcx.ccx, result_ty) {
16831683
let repr = adt::represent_type(ccx, result_ty);
16841684
adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr);
16851685
for (i, arg_datum) in arg_datums.move_iter().enumerate() {

src/librustc/middle/trans/callee.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ pub fn trans_call_inner<'a>(
667667
}
668668
Some(expr::SaveIn(dst)) => Some(dst),
669669
Some(expr::Ignore) => {
670-
if !type_is_voidish(ccx, ret_ty) {
670+
if !type_is_zero_size(ccx, ret_ty) {
671671
Some(alloc_ty(bcx, ret_ty, "__llret"))
672672
} else {
673673
let llty = type_of::type_of(ccx, ret_ty);
@@ -736,7 +736,7 @@ pub fn trans_call_inner<'a>(
736736
match opt_llretslot {
737737
Some(llretslot) => {
738738
if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
739-
!type_is_voidish(bcx.ccx(), ret_ty)
739+
!type_is_zero_size(bcx.ccx(), ret_ty)
740740
{
741741
Store(bcx, llret, llretslot);
742742
}

src/librustc/middle/trans/common.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,33 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
7575
let llty = sizing_type_of(ccx, ty);
7676
llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
7777
}
78-
_ => type_is_voidish(ccx, ty)
78+
_ => type_is_zero_size(ccx, ty)
7979
}
8080
}
8181

82-
pub fn type_is_voidish(ccx: &CrateContext, ty: ty::t) -> bool {
83-
//! Identify types like `()`, bottom, or empty structs, which
84-
//! contain no information at all.
82+
pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
83+
/*!
84+
* Identify types which have size zero at runtime.
85+
*/
86+
8587
use middle::trans::machine::llsize_of_alloc;
8688
use middle::trans::type_of::sizing_type_of;
8789
let llty = sizing_type_of(ccx, ty);
8890
llsize_of_alloc(ccx, llty) == 0
8991
}
9092

93+
pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
94+
/*!
95+
* Identifies types which we declare to be equivalent to `void`
96+
* in C for the purpose of function return types. These are
97+
* `()`, bot, and uninhabited enums. Note that all such types
98+
* are also zero-size, but not all zero-size types use a `void`
99+
* return type (in order to aid with C ABI compatibility).
100+
*/
101+
102+
ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty)
103+
}
104+
91105
pub fn gensym_name(name: &str) -> (Ident, PathElem) {
92106
let name = token::gensym(name);
93107
let ident = Ident::new(name);

src/librustc/middle/trans/datum.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ pub fn appropriate_rvalue_mode(ccx: &CrateContext, ty: ty::t) -> RvalueMode {
171171
* on whether type is immediate or not.
172172
*/
173173

174-
if type_is_voidish(ccx, ty) {
174+
if type_is_zero_size(ccx, ty) {
175175
ByValue
176176
} else if type_is_immediate(ccx, ty) {
177177
ByValue
@@ -583,7 +583,7 @@ fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
583583
* what we are loading.
584584
*/
585585

586-
if type_is_voidish(bcx.ccx(), ty) {
586+
if type_is_zero_size(bcx.ccx(), ty) {
587587
C_undef(type_of::type_of(bcx.ccx(), ty))
588588
} else if ty::type_is_bool(ty) {
589589
LoadRangeAssert(bcx, llptr, 0, 2, lib::llvm::True)
@@ -638,7 +638,7 @@ impl<K:KindOps> Datum<K> {
638638

639639
let _icx = push_ctxt("copy_to_no_check");
640640

641-
if type_is_voidish(bcx.ccx(), self.ty) {
641+
if type_is_zero_size(bcx.ccx(), self.ty) {
642642
return bcx;
643643
}
644644

src/librustc/middle/trans/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>,
474474

475475
ty::RvalueDpsExpr => {
476476
let ty = expr_ty(bcx, expr);
477-
if type_is_voidish(bcx.ccx(), ty) {
477+
if type_is_zero_size(bcx.ccx(), ty) {
478478
bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
479479
nil(bcx, ty)
480480
} else {

src/librustc/middle/trans/foreign.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ pub fn trans_native_call<'a>(
198198
_ => ccx.sess.bug("trans_native_call called on non-function type")
199199
};
200200
let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys);
201-
let ret_def = !type_is_voidish(bcx.ccx(), fn_sig.output);
201+
let ret_def = !return_type_is_void(bcx.ccx(), fn_sig.output);
202202
let fn_type = cabi::compute_abi_info(ccx,
203203
llsig.llarg_tys,
204204
llsig.llret_ty,
@@ -778,7 +778,7 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
778778
_ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
779779
};
780780
let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs);
781-
let ret_def = !type_is_voidish(ccx, fn_sig.output);
781+
let ret_def = !return_type_is_void(ccx, fn_sig.output);
782782
let fn_ty = cabi::compute_abi_info(ccx,
783783
llsig.llarg_tys,
784784
llsig.llret_ty,

src/librustc/middle/trans/intrinsic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
317317
"uninit" => {
318318
// Do nothing, this is effectively a no-op
319319
let retty = substs.tys[0];
320-
if type_is_immediate(ccx, retty) && !type_is_voidish(ccx, retty) {
320+
if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
321321
unsafe {
322322
Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
323323
}
@@ -356,7 +356,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
356356
pluralize(out_type_size)));
357357
}
358358

359-
if !type_is_voidish(ccx, out_type) {
359+
if !return_type_is_void(ccx, out_type) {
360360
let llsrcval = get_param(decl, first_real_arg);
361361
if type_is_immediate(ccx, in_type) {
362362
match fcx.llretptr.get() {

src/librustc/middle/trans/type_of.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ pub fn type_of_rust_fn(cx: &CrateContext,
6868
atys.push_all(type_of_explicit_args(cx, inputs));
6969

7070
// Use the output as the actual return value if it's immediate.
71-
if !use_out_pointer && !type_is_voidish(cx, output) {
72-
Type::func(atys, &lloutputtype)
73-
} else {
71+
if use_out_pointer || return_type_is_void(cx, output) {
7472
Type::func(atys, &Type::void())
73+
} else {
74+
Type::func(atys, &lloutputtype)
7575
}
7676
}
7777

0 commit comments

Comments
 (0)