about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-09-30 21:51:27 -0700
committerbors <bors@rust-lang.org>2013-09-30 21:51:27 -0700
commit1dbc467fd957a0daf3fd935ccce0fc9ea5d1dcd8 (patch)
treea8a5ec24b1c6cb983cc83eb7fecfe9cadded439f
parentbc6dd906a9075f694f562c753e165e1d108e6ec3 (diff)
parentab0a884a7373145222dfbadc8ec741f767cc45d1 (diff)
downloadrust-1dbc467fd957a0daf3fd935ccce0fc9ea5d1dcd8.tar.gz
rust-1dbc467fd957a0daf3fd935ccce0fc9ea5d1dcd8.zip
auto merge of #9643 : thestinger/rust/immediate, r=alexcrichton
-rw-r--r--src/librustc/middle/trans/base.rs4
-rw-r--r--src/librustc/middle/trans/common.rs27
-rw-r--r--src/librustc/middle/trans/datum.rs6
-rw-r--r--src/librustc/middle/trans/glue.rs16
-rw-r--r--src/librustc/middle/trans/intrinsic.rs6
-rw-r--r--src/librustc/middle/trans/type_of.rs4
-rw-r--r--src/librustc/middle/ty.rs32
-rw-r--r--src/test/run-pass/issue-9446.rs38
8 files changed, 84 insertions, 49 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 1749f8e3f6f..264ad3c7c57 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -1121,13 +1121,13 @@ pub fn do_spill_noroot(cx: @mut Block, v: ValueRef) -> ValueRef {
 
 pub fn spill_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
     let _icx = push_ctxt("spill_if_immediate");
-    if ty::type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
+    if type_is_immediate(cx.tcx(), t) { return do_spill(cx, v, t); }
     return v;
 }
 
 pub fn load_if_immediate(cx: @mut Block, v: ValueRef, t: ty::t) -> ValueRef {
     let _icx = push_ctxt("load_if_immediate");
-    if ty::type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
+    if type_is_immediate(cx.tcx(), t) { return Load(cx, v); }
     return v;
 }
 
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 322050331a2..f030fb4996b 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -15,7 +15,7 @@ use driver::session;
 use driver::session::Session;
 use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef};
 use lib::llvm::{True, False, Bool};
-use lib::llvm::{llvm};
+use lib::llvm::llvm;
 use lib;
 use middle::lang_items::LangItem;
 use middle::trans::base;
@@ -28,17 +28,17 @@ use middle::ty::substs;
 use middle::ty;
 use middle::typeck;
 use middle::borrowck::root_map_key;
-use util::ppaux::{Repr};
+use util::ppaux::Repr;
 
 use middle::trans::type_::Type;
 
 use std::c_str::ToCStr;
 use std::cast::transmute;
 use std::cast;
-use std::hashmap::{HashMap};
+use std::hashmap::HashMap;
 use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
 use std::vec;
-use syntax::ast::{Name,Ident};
+use syntax::ast::{Name, Ident};
 use syntax::ast_map::{path, path_elt, path_pretty_name};
 use syntax::codemap::Span;
 use syntax::parse::token;
@@ -46,6 +46,25 @@ use syntax::{ast, ast_map};
 
 pub use middle::trans::context::CrateContext;
 
+fn type_is_newtype_immediate(cx: ty::ctxt, ty: ty::t) -> bool {
+    match ty::get(ty).sty {
+        ty::ty_struct(def_id, ref substs) => {
+            let fields = ty::struct_fields(cx, def_id, substs);
+            fields.len() == 1 &&
+                fields[0].ident.name == token::special_idents::unnamed_field.name &&
+                type_is_immediate(cx, fields[0].mt.ty)
+        }
+        _ => false
+    }
+}
+
+pub fn type_is_immediate(cx: ty::ctxt, ty: ty::t) -> bool {
+    ty::type_is_scalar(ty) || ty::type_is_boxed(ty) ||
+        ty::type_is_unique(ty) || ty::type_is_region_ptr(ty) ||
+        type_is_newtype_immediate(cx, ty) ||
+        ty::type_is_simd(cx, ty)
+}
+
 pub fn gensym_name(name: &str) -> (Ident, path_elt) {
     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 8ee38b950bf..e48174b04f8 100644
--- a/src/librustc/middle/trans/datum.rs
+++ b/src/librustc/middle/trans/datum.rs
@@ -197,7 +197,7 @@ pub fn appropriate_mode(tcx: ty::ctxt, ty: ty::t) -> DatumMode {
 
     if ty::type_is_voidish(ty) {
         ByValue
-    } else if ty::type_is_immediate(tcx, ty) {
+    } else if type_is_immediate(tcx, ty) {
         ByValue
     } else {
         ByRef(RevokeClean)
@@ -667,7 +667,7 @@ impl Datum {
                     ByValue => {
                         // Actually, this case cannot happen right
                         // now, because enums are never immediate.
-                        assert!(ty::type_is_immediate(bcx.tcx(), ty));
+                        assert!(type_is_immediate(bcx.tcx(), ty));
                         (Some(Datum {ty: ty, ..*self}), bcx)
                     }
                 };
@@ -699,7 +699,7 @@ impl Datum {
                         )
                     }
                     ByValue => {
-                        assert!(ty::type_is_immediate(bcx.tcx(), ty));
+                        assert!(type_is_immediate(bcx.tcx(), ty));
                         (
                             Some(Datum {
                                 val: ExtractValue(bcx, self.val, 0),
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index a10f53ebcbc..cecea270330 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -77,19 +77,9 @@ pub fn drop_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
 
 pub fn drop_ty_immediate(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
     let _icx = push_ctxt("drop_ty_immediate");
-    match ty::get(t).sty {
-        ty::ty_uniq(_)
-      | ty::ty_evec(_, ty::vstore_uniq)
-      | ty::ty_estr(ty::vstore_uniq) => {
-        free_ty_immediate(bcx, v, t)
-      }
-        ty::ty_box(_) | ty::ty_opaque_box
-      | ty::ty_evec(_, ty::vstore_box)
-      | ty::ty_estr(ty::vstore_box) => {
-        decr_refcnt_maybe_free(bcx, v, None, t)
-      }
-      _ => bcx.tcx().sess.bug("drop_ty_immediate: non-box ty")
-    }
+    let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
+    Store(bcx, v, vp);
+    drop_ty(bcx, vp, t)
 }
 
 pub fn free_ty(cx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs
index 04ffb393b5e..7933e97a602 100644
--- a/src/librustc/middle/trans/intrinsic.rs
+++ b/src/librustc/middle/trans/intrinsic.rs
@@ -278,7 +278,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
         "uninit" => {
             // Do nothing, this is effectively a no-op
             let retty = substs.tys[0];
-            if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) {
+            if type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) {
                 unsafe {
                     Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref()));
                 }
@@ -316,7 +316,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
 
             if !ty::type_is_voidish(out_type) {
                 let llsrcval = get_param(decl, first_real_arg);
-                if ty::type_is_immediate(ccx.tcx, in_type) {
+                if type_is_immediate(ccx.tcx, in_type) {
                     match fcx.llretptr {
                         Some(llretptr) => {
                             Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to()));
@@ -335,7 +335,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
                             }
                         }
                     }
-                } else if ty::type_is_immediate(ccx.tcx, out_type) {
+                } else if type_is_immediate(ccx.tcx, out_type) {
                     let llsrcptr = PointerCast(bcx, llsrcval, llouttype.ptr_to());
                     let ll_load = Load(bcx, llsrcptr);
                     Ret(bcx, ll_load);
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index 945d5a048bb..aab24f8365b 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -21,11 +21,11 @@ use syntax::ast;
 use syntax::opt_vec;
 
 pub fn arg_is_indirect(ccx: &CrateContext, arg_ty: ty::t) -> bool {
-    !ty::type_is_immediate(ccx.tcx, arg_ty)
+    !type_is_immediate(ccx.tcx, arg_ty)
 }
 
 pub fn return_uses_outptr(tcx: ty::ctxt, ty: ty::t) -> bool {
-    !ty::type_is_immediate(tcx, ty)
+    !type_is_immediate(tcx, ty)
 }
 
 pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: ty::t) -> Type {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index bcf4de08073..ed103f66915 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -1752,25 +1752,6 @@ pub fn type_is_scalar(ty: t) -> bool {
     }
 }
 
-fn type_is_newtype_immediate(cx: ctxt, ty: t) -> bool {
-    match get(ty).sty {
-        ty_struct(def_id, ref substs) => {
-            let fields = struct_fields(cx, def_id, substs);
-            fields.len() == 1 &&
-                fields[0].ident.name == token::special_idents::unnamed_field.name &&
-                type_is_immediate(cx, fields[0].mt.ty)
-        }
-        _ => false
-    }
-}
-
-pub fn type_is_immediate(cx: ctxt, ty: t) -> bool {
-    return type_is_scalar(ty) || type_is_boxed(ty) ||
-        type_is_unique(ty) || type_is_region_ptr(ty) ||
-        type_is_newtype_immediate(cx, ty) ||
-        type_is_simd(cx, ty);
-}
-
 pub fn type_needs_drop(cx: ctxt, ty: t) -> bool {
     type_contents(cx, ty).needs_drop(cx)
 }
@@ -2538,6 +2519,13 @@ pub fn type_structurally_contains_uniques(cx: ctxt, ty: t) -> bool {
     });
 }
 
+pub fn type_is_trait(ty: t) -> bool {
+    match get(ty).sty {
+        ty_trait(*) => true,
+        _ => false
+    }
+}
+
 pub fn type_is_integral(ty: t) -> bool {
     match get(ty).sty {
       ty_infer(IntVar(_)) | ty_int(_) | ty_uint(_) => true,
@@ -3289,10 +3277,10 @@ pub fn expr_kind(tcx: ctxt,
         ast::ExprCast(*) => {
             match tcx.node_types.find(&(expr.id as uint)) {
                 Some(&t) => {
-                    if ty::type_is_immediate(tcx, t) {
-                        RvalueDatumExpr
-                    } else {
+                    if type_is_trait(t) {
                         RvalueDpsExpr
+                    } else {
+                        RvalueDatumExpr
                     }
                 }
                 None => {
diff --git a/src/test/run-pass/issue-9446.rs b/src/test/run-pass/issue-9446.rs
new file mode 100644
index 00000000000..e97960b3f02
--- /dev/null
+++ b/src/test/run-pass/issue-9446.rs
@@ -0,0 +1,38 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+struct Wrapper(~str);
+
+impl Wrapper {
+    pub fn new(wrapped: ~str) -> Wrapper {
+        Wrapper(wrapped)
+    }
+
+    pub fn say_hi(&self) {
+        println(fmt!("hello %s", **self));
+    }
+}
+
+impl Drop for Wrapper {
+    fn drop(&mut self) {}
+}
+
+pub fn main() {
+    {
+        // This runs without complaint.
+        let x = Wrapper::new(~"Bob");
+        x.say_hi();
+    }
+    {
+        // This fails to compile, circa 0.8-89-gc635fba.
+        // error: internal compiler error: drop_ty_immediate: non-box ty
+        Wrapper::new(~"Bob").say_hi();
+    }
+}