Skip to content

Commit 81c5fd8

Browse files
committed
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
1 parent 6ba9acd commit 81c5fd8

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

src/libcore/intrinsics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ extern "rust-intrinsic" {
198198
pub fn pref_align_of<T>() -> uint;
199199

200200
/// Get a static pointer to a type descriptor.
201+
#[cfg(not(stage0))]
202+
pub fn get_tydesc<T: ?Sized>() -> *const TyDesc;
203+
204+
#[cfg(stage0)]
201205
pub fn get_tydesc<T>() -> *const TyDesc;
202206

203207
/// Gets an identifier which is globally unique to the specified type. This

src/librustc_trans/trans/glue.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,12 +346,14 @@ fn size_and_align_of_dst<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, info:
346346
let align_ptr = GEPi(bcx, info, &[2u]);
347347
(Load(bcx, size_ptr), Load(bcx, align_ptr))
348348
}
349-
ty::ty_vec(unit_ty, None) => {
350-
// The info in this case is the length of the vec, so the size is that
349+
ty::ty_vec(_, None) | ty::ty_str => {
350+
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
351+
// The info in this case is the length of the str, so the size is that
351352
// times the unit size.
352353
let llunit_ty = sizing_type_of(bcx.ccx(), unit_ty);
354+
let unit_align = llalign_of_min(bcx.ccx(), llunit_ty);
353355
let unit_size = llsize_of_alloc(bcx.ccx(), llunit_ty);
354-
(Mul(bcx, info, C_uint(bcx.ccx(), unit_size)), C_uint(bcx.ccx(), 8u))
356+
(Mul(bcx, info, C_uint(bcx.ccx(), unit_size)), C_uint(bcx.ccx(), unit_align))
355357
}
356358
_ => bcx.sess().bug(&format!("Unexpected unsized type, found {}",
357359
bcx.ty_to_string(t))[])
@@ -456,8 +458,11 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
456458
&[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
457459
None);
458460
bcx
459-
}
460-
ty::ty_vec(ty, None) => tvec::make_drop_glue_unboxed(bcx, v0, ty, false),
461+
},
462+
ty::ty_vec(_, None) | ty::ty_str => {
463+
let unit_ty = ty::sequence_element_type(bcx.tcx(), t);
464+
tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, false)
465+
},
461466
_ => {
462467
assert!(type_is_sized(bcx.tcx(), t));
463468
if type_needs_drop(bcx.tcx(), t) &&

src/test/run-pass/issue-21058.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![allow(unstable)]
12+
13+
struct NT(str);
14+
struct DST { a: u32, b: str }
15+
16+
fn main() {
17+
// get_tydesc should support unsized types
18+
assert!(unsafe {(
19+
// Slice
20+
(*std::intrinsics::get_tydesc::<[u8]>()).name,
21+
// str
22+
(*std::intrinsics::get_tydesc::<str>()).name,
23+
// Trait
24+
(*std::intrinsics::get_tydesc::<Copy>()).name,
25+
// Newtype
26+
(*std::intrinsics::get_tydesc::<NT>()).name,
27+
// DST
28+
(*std::intrinsics::get_tydesc::<DST>()).name
29+
)} == ("[u8]", "str", "core::marker::Copy + 'static", "NT", "DST"));
30+
}

0 commit comments

Comments
 (0)