From 81c5fd8e1f542bf680e48d1f11d6d9e9d7001563 Mon Sep 17 00:00:00 2001 From: Diggory Blake Date: Thu, 15 Jan 2015 06:54:51 +0000 Subject: [PATCH] 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 --- src/libcore/intrinsics.rs | 4 ++++ src/librustc_trans/trans/glue.rs | 15 ++++++++++----- src/test/run-pass/issue-21058.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 src/test/run-pass/issue-21058.rs diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 5924d515dda5..978e8a19737b 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -198,6 +198,10 @@ extern "rust-intrinsic" { pub fn pref_align_of() -> uint; /// Get a static pointer to a type descriptor. + #[cfg(not(stage0))] + pub fn get_tydesc() -> *const TyDesc; + + #[cfg(stage0)] pub fn get_tydesc() -> *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 a79bb6ca1647..d3f3f34b76bb 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 000000000000..cbce577451fa --- /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 or the MIT license +// , 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::()).name, + // Trait + (*std::intrinsics::get_tydesc::()).name, + // Newtype + (*std::intrinsics::get_tydesc::()).name, + // DST + (*std::intrinsics::get_tydesc::()).name + )} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST")); +}