about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDiggory Blake <diggsey@googlemail.com>2015-01-15 06:54:51 +0000
committerDiggory Blake <diggsey@googlemail.com>2015-01-15 06:54:51 +0000
commit81c5fd8e1f542bf680e48d1f11d6d9e9d7001563 (patch)
tree54decb494014787036148de821a4a805be05c44c
parent6ba9acd8ab0fc6ab5ce3776a1a50fe1431125ed8 (diff)
downloadrust-81c5fd8e1f542bf680e48d1f11d6d9e9d7001563.tar.gz
rust-81c5fd8e1f542bf680e48d1f11d6d9e9d7001563.zip
Allow get_tydesc intrinsic to accept unsized types
Fix tabs

Added missing ty_str cases when generating type descriptions

Reduce code duplication and improve test
-rw-r--r--src/libcore/intrinsics.rs4
-rw-r--r--src/librustc_trans/trans/glue.rs15
-rw-r--r--src/test/run-pass/issue-21058.rs30
3 files changed, 44 insertions, 5 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 5924d515dda..978e8a19737 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -198,6 +198,10 @@ extern "rust-intrinsic" {
     pub fn pref_align_of<T>() -> uint;
 
     /// Get a static pointer to a type descriptor.
+    #[cfg(not(stage0))]
+    pub fn get_tydesc<T: ?Sized>() -> *const TyDesc;
+
+    #[cfg(stage0)]
     pub fn get_tydesc<T>() -> *const TyDesc;
 
     /// Gets an identifier which is globally unique to the specified type. This
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index a79bb6ca164..d3f3f34b76b 100644
--- a/src/librustc_trans/trans/glue.rs
+++ b/src/librustc_trans/trans/glue.rs
@@ -346,12 +346,14 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info:
             let align_ptr = GEPi(bcx, info, &[2u]);
             (Load(bcx, size_ptr), Load(bcx, align_ptr))
         }
-        ty::ty_vec(unit_ty, None) => {
-            // The info in this case is the length of the vec, so the size is that
+        ty::ty_vec(_, None) | ty::ty_str => {
+            let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
+            // The info in this case is the length of the str, so the size is that
             // times the unit size.
             let llunit_ty = sizing_type_of(bcx.ccx(), unit_ty);
+            let unit_align = llalign_of_min(bcx.ccx(), llunit_ty);
             let unit_size = llsize_of_alloc(bcx.ccx(), llunit_ty);
-            (Mul(bcx, info, C_uint(bcx.ccx(), unit_size)), C_uint(bcx.ccx(), 8u))
+            (Mul(bcx, info, C_uint(bcx.ccx(), unit_size)), C_uint(bcx.ccx(), unit_align))
         }
         _ => bcx.sess().bug(&format!("Unexpected unsized type, found {}",
                                     bcx.ty_to_string(t))[])
@@ -456,8 +458,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                  &[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
                  None);
             bcx
-        }
-        ty::ty_vec(ty, None) => tvec::make_drop_glue_unboxed(bcx, v0, ty, false),
+        },
+        ty::ty_vec(_, None) | ty::ty_str => {
+            let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
+            tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, false)
+        },
         _ => {
             assert!(type_is_sized(bcx.tcx(), t));
             if type_needs_drop(bcx.tcx(), t) &&
diff --git a/src/test/run-pass/issue-21058.rs b/src/test/run-pass/issue-21058.rs
new file mode 100644
index 00000000000..cbce577451f
--- /dev/null
+++ b/src/test/run-pass/issue-21058.rs
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+#![allow(unstable)]
+
+struct NT(str);
+struct DST { a: u32, b: str }
+
+fn main() {
+    // get_tydesc should support unsized types
+    assert!(unsafe {(
+        // Slice
+        (*std::intrinsics::get_tydesc::<[u8]>()).name,
+        // str
+        (*std::intrinsics::get_tydesc::<str>()).name,
+        // Trait
+        (*std::intrinsics::get_tydesc::<Copy>()).name,
+        // Newtype
+        (*std::intrinsics::get_tydesc::<NT>()).name,
+        // DST
+        (*std::intrinsics::get_tydesc::<DST>()).name
+    )} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST"));
+}