about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-02 07:56:36 -0700
committerbors <bors@rust-lang.org>2013-10-02 07:56:36 -0700
commitc44826fdcd036982b955407677c5ec4ce1f834ce (patch)
treeb5a277bed46512e925d35213396ba2f6a9e7d184
parent17548378a707fae752dc722e2fb767a65195e422 (diff)
parentf2932e46614ab0f91f7dfd064cadf1e3db2a9667 (diff)
downloadrust-c44826fdcd036982b955407677c5ec4ce1f834ce.tar.gz
rust-c44826fdcd036982b955407677c5ec4ce1f834ce.zip
auto merge of #9677 : thestinger/rust/immediate, r=huonw
C-like enums are excluded from this for now, because the code paths
specific to them need to be changed.

    fn foo() -> Option<~int> { Some(~5) }

Before:

    ; Function Attrs: uwtable
    define void @_ZN3foo18hdec6e36682b87eeaf4v0.0E(%"enum.std::option::Option<~int>[#1]"* noalias nocapture sret, { i64, %tydesc*, i8*, i8*, i8 }* nocapture readnone) #0 {
    "function top level":
      %2 = tail call %"enum.std::libc::types::common::c95::c_void[#1]"* @"_ZN2rt11global_heap10malloc_raw17h56c543b77f9b78aY11v0.9$x2dpreE"({ i64, %tydesc*, i8*, i8*, i8 }* undef, i64 8)
      %3 = bitcast %"enum.std::libc::types::common::c95::c_void[#1]"* %2 to i64*
      store i64 5, i64* %3, align 8
      %4 = getelementptr inbounds %"enum.std::option::Option<~int>[#1]"* %0, i64 0, i32 0
      store i64* %3, i64** %4, align 8
      ret void
    }

After:

    ; Function Attrs: uwtable
    define %"enum.std::option::Option<~int>[#1]" @_ZN3foo18h2cbf6557a3143edah4v0.0E({ i64, %tydesc*, i8*, i8*, i8 }* nocapture readnone) #0 {
    "function top level":
      %1 = tail call %"enum.std::libc::types::common::c95::c_void[#1]"* @"_ZN2rt11global_heap10malloc_raw18hb1e9dd1beab35edau11v0.9$x2dpreE"({ i64, %tydesc*, i8*, i8*, i8 }* undef, i64 8)
      %2 = bitcast %"enum.std::libc::types::common::c95::c_void[#1]"* %1 to i64*
      store i64 5, i64* %2, align 8
      %oldret = insertvalue %"enum.std::option::Option<~int>[#1]" undef, i64* %2, 0
      ret %"enum.std::option::Option<~int>[#1]" %oldret
    }
-rw-r--r--src/librustc/middle/trans/base.rs4
-rw-r--r--src/librustc/middle/trans/callee.rs4
-rw-r--r--src/librustc/middle/trans/common.rs8
-rw-r--r--src/librustc/middle/trans/datum.rs10
-rw-r--r--src/librustc/middle/trans/expr.rs4
-rw-r--r--src/librustc/middle/trans/foreign.rs4
-rw-r--r--src/librustc/middle/trans/intrinsic.rs2
-rw-r--r--src/librustc/middle/trans/type_of.rs2
-rw-r--r--src/librustc/middle/ty.rs4
9 files changed, 23 insertions, 19 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 8182dd9339e..dea86286279 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1733,7 +1733,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext,
         fcx.alloca_insert_pt = Some(llvm::LLVMGetFirstInstruction(entry_bcx.llbb));
     }
 
-    if !ty::type_is_voidish(substd_output_type) {
+    if !ty::type_is_voidish(ccx.tcx, substd_output_type) {
         // If the function returns nil/bot, there is no real return
         // value, so do not set `llretptr`.
         if !skip_retptr || uses_outptr {
@@ -1964,7 +1964,7 @@ pub fn trans_closure(ccx: @mut 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() || ty::type_is_voidish(block_ty) {
+    if body.expr.is_none() || ty::type_is_voidish(bcx.tcx(), block_ty) {
         bcx = controlflow::trans_block(bcx, body, expr::Ignore);
     } else {
         let dest = expr::SaveIn(fcx.llretptr.unwrap());
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 700d9c7597b..839313f7bbe 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -660,7 +660,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
             }
             Some(expr::SaveIn(dst)) => Some(dst),
             Some(expr::Ignore) => {
-                if !ty::type_is_voidish(ret_ty) {
+                if !ty::type_is_voidish(in_cx.tcx(), ret_ty) {
                     Some(alloc_ty(bcx, ret_ty, "__llret"))
                 } else {
                     unsafe {
@@ -735,7 +735,7 @@ pub fn trans_call_inner(in_cx: @mut Block,
             match opt_llretslot {
                 Some(llretslot) => {
                     if !type_of::return_uses_outptr(bcx.ccx(), ret_ty) &&
-                        !ty::type_is_voidish(ret_ty)
+                        !ty::type_is_voidish(bcx.tcx(), ret_ty)
                     {
                         Store(bcx, llret, llretslot);
                     }
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 8fbf8b1813c..bbed6324543 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -69,9 +69,13 @@ pub fn type_is_immediate(ccx: &mut CrateContext, ty: ty::t) -> bool {
     if simple {
         return true;
     }
+    // FIXME: #9651: C-like enums should also be immediate
+    if ty::type_is_c_like_enum(ccx.tcx, ty) {
+        return false;
+    }
     match ty::get(ty).sty {
-        // FIXME: #9651: small `ty_struct` and `ty_enum` should also be immediate
-        ty::ty_tup(*) => {
+        // FIXME: #9651: small `ty_struct` should also be immediate
+        ty::ty_enum(*) | ty::ty_tup(*) => {
             let llty = sizing_type_of(ccx, ty);
             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type)
         }
diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs
index c17262b9282..a70b38fca17 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -195,7 +195,7 @@ pub fn appropriate_mode(ccx: &mut CrateContext, ty: ty::t) -> DatumMode {
      * on whether type is immediate or not.
      */
 
-    if ty::type_is_voidish(ty) {
+    if ty::type_is_voidish(ccx.tcx, ty) {
         ByValue
     } else if type_is_immediate(ccx, ty) {
         ByValue
@@ -271,7 +271,7 @@ impl Datum {
 
         let _icx = push_ctxt("copy_to");
 
-        if ty::type_is_voidish(self.ty) {
+        if ty::type_is_voidish(bcx.tcx(), self.ty) {
             return bcx;
         }
 
@@ -343,7 +343,7 @@ impl Datum {
         debug2!("move_to(self={}, action={:?}, dst={})",
                self.to_str(bcx.ccx()), action, bcx.val_to_str(dst));
 
-        if ty::type_is_voidish(self.ty) {
+        if ty::type_is_voidish(bcx.tcx(), self.ty) {
             return bcx;
         }
 
@@ -432,7 +432,7 @@ impl Datum {
          *
          * Yields the value itself. */
 
-        if ty::type_is_voidish(self.ty) {
+        if ty::type_is_voidish(bcx.tcx(), self.ty) {
             C_nil()
         } else {
             match self.mode {
@@ -469,7 +469,7 @@ impl Datum {
         match self.mode {
             ByRef(_) => self.val,
             ByValue => {
-                if ty::type_is_voidish(self.ty) {
+                if ty::type_is_voidish(bcx.tcx(), self.ty) {
                     C_null(type_of::type_of(bcx.ccx(), self.ty).ptr_to())
                 } else {
                     let slot = alloc_ty(bcx, self.ty, "");
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 65e0f17f651..60a2b08758d 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -440,7 +440,7 @@ pub fn trans_into(bcx: @mut Block, expr: &ast::Expr, dest: Dest) -> @mut Block {
     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
 
     let dest = {
-        if ty::type_is_voidish(ty) {
+        if ty::type_is_voidish(bcx.tcx(), ty) {
             Ignore
         } else {
             dest
@@ -531,7 +531,7 @@ fn trans_to_datum_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
 
         ty::RvalueDpsExpr => {
             let ty = expr_ty(bcx, expr);
-            if ty::type_is_voidish(ty) {
+            if ty::type_is_voidish(bcx.tcx(), ty) {
                 bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
                 return nil(bcx, ty);
             } else {
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 84ee1cc8ef3..c5f9e8fdee0 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -177,7 +177,7 @@ pub fn trans_native_call(bcx: @mut Block,
         _ => ccx.sess.bug("trans_native_call called on non-function type")
     };
     let llsig = foreign_signature(ccx, &fn_sig);
-    let ret_def = !ty::type_is_voidish(fn_sig.output);
+    let ret_def = !ty::type_is_voidish(bcx.tcx(), fn_sig.output);
     let fn_type = cabi::compute_abi_info(ccx,
                                          llsig.llarg_tys,
                                          llsig.llret_ty,
@@ -718,7 +718,7 @@ fn foreign_types_for_fn_ty(ccx: &mut CrateContext,
         _ => ccx.sess.bug("foreign_types_for_fn_ty called on non-function type")
     };
     let llsig = foreign_signature(ccx, &fn_sig);
-    let ret_def = !ty::type_is_voidish(fn_sig.output);
+    let ret_def = !ty::type_is_voidish(ccx.tcx, 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 6d3b1396fc5..fd097fdd0b4 100644
--- a/src/librustc/middle/trans/intrinsic.rs
+++ b/src/librustc/middle/trans/intrinsic.rs
@@ -321,7 +321,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
                                          pluralize(out_type_size)));
             }
 
-            if !ty::type_is_voidish(out_type) {
+            if !ty::type_is_voidish(ccx.tcx, out_type) {
                 let llsrcval = get_param(decl, first_real_arg);
                 if type_is_immediate(ccx, in_type) {
                     match fcx.llretptr {
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 3f37f12bc30..8667d7224e7 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -62,7 +62,7 @@ pub fn type_of_rust_fn(cx: &mut 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 && !ty::type_is_voidish(output) {
+    if !use_out_pointer && !ty::type_is_voidish(cx.tcx, output) {
         Type::func(atys, &lloutputtype)
     } else {
         Type::func(atys, &Type::void())
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 84ebda5db5c..bd099e81a17 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1566,9 +1566,9 @@ pub fn subst(cx: ctxt,
 
 // Type utilities
 
-pub fn type_is_voidish(ty: t) -> bool {
+pub fn type_is_voidish(tcx: ctxt, ty: t) -> bool {
     //! "nil" and "bot" are void types in that they represent 0 bits of information
-    type_is_nil(ty) || type_is_bot(ty)
+    type_is_nil(ty) || type_is_bot(ty) || type_is_empty(tcx, ty)
 }
 
 pub fn type_is_nil(ty: t) -> bool { get(ty).sty == ty_nil }