about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-01-16 19:10:17 -0500
committerNiko Matsakis <niko@alum.mit.edu>2014-01-16 19:10:17 -0500
commit5e7657fafb62b81eb68cb63b2a42e7b77ab9fce6 (patch)
tree881800d0aed063e1717547c3741c8c7024640580 /src
parent76c90283ce9de476357abf9a5fed79e86a2f1f53 (diff)
downloadrust-5e7657fafb62b81eb68cb63b2a42e7b77ab9fce6.tar.gz
rust-5e7657fafb62b81eb68cb63b2a42e7b77ab9fce6.zip
Distinguish zero-size types from those that we return as void
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/trans/base.rs6
-rw-r--r--src/librustc/middle/trans/callee.rs4
-rw-r--r--src/librustc/middle/trans/common.rs22
-rw-r--r--src/librustc/middle/trans/datum.rs6
-rw-r--r--src/librustc/middle/trans/expr.rs2
-rw-r--r--src/librustc/middle/trans/foreign.rs4
-rw-r--r--src/librustc/middle/trans/intrinsic.rs4
-rw-r--r--src/librustc/middle/trans/type_of.rs6
8 files changed, 34 insertions, 20 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index f908732ea0a..ef40629946d 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1320,7 +1320,7 @@ pub fn init_function<'a>(
         }
     };
 
-    if !type_is_voidish(fcx.ccx, substd_output_type) {
+    if !return_type_is_void(fcx.ccx, substd_output_type) {
         // If the function returns nil/bot, there is no real return
         // value, so do not set `llretptr`.
         if !skip_retptr || fcx.caller_expects_out_pointer {
@@ -1539,7 +1539,7 @@ pub fn trans_closure(ccx: @CrateContext,
     // translation calls that don't have a return value (trans_crate,
     // trans_mod, trans_item, et cetera) and those that do
     // (trans_block, trans_expr, et cetera).
-    if body.expr.is_none() || type_is_voidish(bcx.ccx(), block_ty) {
+    if body.expr.is_none() || type_is_zero_size(bcx.ccx(), block_ty) {
         bcx = controlflow::trans_block(bcx, body, expr::Ignore);
     } else {
         let dest = expr::SaveIn(fcx.llretptr.get().unwrap());
@@ -1679,7 +1679,7 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: @CrateContext,
 
     let bcx = fcx.entry_bcx.get().unwrap();
 
-    if !type_is_voidish(fcx.ccx, result_ty) {
+    if !type_is_zero_size(fcx.ccx, result_ty) {
         let repr = adt::represent_type(ccx, result_ty);
         adt::trans_start_init(bcx, repr, fcx.llretptr.get().unwrap(), disr);
         for (i, arg_datum) in arg_datums.move_iter().enumerate() {
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 7cc80318f87..27903e74e07 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -667,7 +667,7 @@ pub fn trans_call_inner<'a>(
         }
         Some(expr::SaveIn(dst)) => Some(dst),
         Some(expr::Ignore) => {
-            if !type_is_voidish(ccx, ret_ty) {
+            if !type_is_zero_size(ccx, ret_ty) {
                 Some(alloc_ty(bcx, ret_ty, "__llret"))
             } else {
                 let llty = type_of::type_of(ccx, ret_ty);
@@ -736,7 +736,7 @@ pub fn trans_call_inner<'a>(
         match opt_llretslot {
             Some(llretslot) => {
                 if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
-                    !type_is_voidish(bcx.ccx(), ret_ty)
+                    !type_is_zero_size(bcx.ccx(), ret_ty)
                 {
                     Store(bcx, llret, llretslot);
                 }
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 90083541e42..e466e4da38d 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -75,19 +75,33 @@ pub fn type_is_immediate(ccx: &CrateContext, ty: ty::t) -> bool {
             let llty = sizing_type_of(ccx, ty);
             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
         }
-        _ => type_is_voidish(ccx, ty)
+        _ => type_is_zero_size(ccx, ty)
     }
 }
 
-pub fn type_is_voidish(ccx: &CrateContext, ty: ty::t) -> bool {
-    //! Identify types like `()`, bottom, or empty structs, which
-    //! contain no information at all.
+pub fn type_is_zero_size(ccx: &CrateContext, ty: ty::t) -> bool {
+    /*!
+     * Identify types which have size zero at runtime.
+     */
+
     use middle::trans::machine::llsize_of_alloc;
     use middle::trans::type_of::sizing_type_of;
     let llty = sizing_type_of(ccx, ty);
     llsize_of_alloc(ccx, llty) == 0
 }
 
+pub fn return_type_is_void(ccx: &CrateContext, ty: ty::t) -> bool {
+    /*!
+     * Identifies types which we declare to be equivalent to `void`
+     * in C for the purpose of function return types. These are
+     * `()`, bot, and uninhabited enums. Note that all such types
+     * are also zero-size, but not all zero-size types use a `void`
+     * return type (in order to aid with C ABI compatibility).
+     */
+
+    ty::type_is_nil(ty) || ty::type_is_bot(ty) || ty::type_is_empty(ccx.tcx, ty)
+}
+
 pub fn gensym_name(name: &str) -> (Ident, PathElem) {
     let name = token::gensym(name);
     let ident = Ident::new(name);
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index 624ff5f6ba1..467501449b8 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -171,7 +171,7 @@ pub fn appropriate_rvalue_mode(ccx: &CrateContext, ty: ty::t) -> RvalueMode {
      * on whether type is immediate or not.
      */
 
-    if type_is_voidish(ccx, ty) {
+    if type_is_zero_size(ccx, ty) {
         ByValue
     } else if type_is_immediate(ccx, ty) {
         ByValue
@@ -583,7 +583,7 @@ fn load<'a>(bcx: &'a Block<'a>, llptr: ValueRef, ty: ty::t) -> ValueRef {
      * what we are loading.
      */
 
-    if type_is_voidish(bcx.ccx(), ty) {
+    if type_is_zero_size(bcx.ccx(), ty) {
         C_undef(type_of::type_of(bcx.ccx(), ty))
     } else if ty::type_is_bool(ty) {
         LoadRangeAssert(bcx, llptr, 0, 2, lib::llvm::True)
@@ -638,7 +638,7 @@ impl<K:KindOps> Datum<K> {
 
         let _icx = push_ctxt("copy_to_no_check");
 
-        if type_is_voidish(bcx.ccx(), self.ty) {
+        if type_is_zero_size(bcx.ccx(), self.ty) {
             return bcx;
         }
 
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 9ae8280428d..36fc927b64c 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -474,7 +474,7 @@ fn trans_unadjusted<'a>(bcx: &'a Block<'a>,
 
         ty::RvalueDpsExpr => {
             let ty = expr_ty(bcx, expr);
-            if type_is_voidish(bcx.ccx(), ty) {
+            if type_is_zero_size(bcx.ccx(), ty) {
                 bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
                 nil(bcx, ty)
             } else {
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 9ba05352b34..083a1c6988d 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -198,7 +198,7 @@ pub fn trans_native_call<'a>(
         _ => ccx.sess.bug("trans_native_call called on non-function type")
     };
     let llsig = foreign_signature(ccx, &fn_sig, passed_arg_tys);
-    let ret_def = !type_is_voidish(bcx.ccx(), fn_sig.output);
+    let ret_def = !return_type_is_void(bcx.ccx(), fn_sig.output);
     let fn_type = cabi::compute_abi_info(ccx,
                                          llsig.llarg_tys,
                                          llsig.llret_ty,
@@ -778,7 +778,7 @@ fn foreign_types_for_fn_ty(ccx: &CrateContext,
         _ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
     };
     let llsig = foreign_signature(ccx, &fn_sig, fn_sig.inputs);
-    let ret_def = !type_is_voidish(ccx, fn_sig.output);
+    let ret_def = !return_type_is_void(ccx, fn_sig.output);
     let fn_ty = cabi::compute_abi_info(ccx,
                                        llsig.llarg_tys,
                                        llsig.llret_ty,
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs
index b1537738646..1fc749bb687 100644
--- a/src/librustc/middle/trans/intrinsic.rs
+++ b/src/librustc/middle/trans/intrinsic.rs
@@ -317,7 +317,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
         "uninit" => {
             // Do nothing, this is effectively a no-op
             let retty = substs.tys[0];
-            if type_is_immediate(ccx, retty) && !type_is_voidish(ccx, retty) {
+            if type_is_immediate(ccx, retty) && !return_type_is_void(ccx, retty) {
                 unsafe {
                     Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
                 }
@@ -356,7 +356,7 @@ pub fn trans_intrinsic(ccx: @CrateContext,
                                          pluralize(out_type_size)));
             }
 
-            if !type_is_voidish(ccx, out_type) {
+            if !return_type_is_void(ccx, out_type) {
                 let llsrcval = get_param(decl, first_real_arg);
                 if type_is_immediate(ccx, in_type) {
                     match fcx.llretptr.get() {
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 3aab6d51619..4db89fbecce 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -68,10 +68,10 @@ pub fn type_of_rust_fn(cx: &CrateContext,
     atys.push_all(type_of_explicit_args(cx, inputs));
 
     // Use the output as the actual return value if it's immediate.
-    if !use_out_pointer && !type_is_voidish(cx, output) {
-        Type::func(atys, &lloutputtype)
-    } else {
+    if use_out_pointer || return_type_is_void(cx, output) {
         Type::func(atys, &Type::void())
+    } else {
+        Type::func(atys, &lloutputtype)
     }
 }