From e256b7f049b44fa697b9f9c5e75b4433a7d9ffdf Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Sun, 15 Mar 2015 04:01:57 +0200 Subject: [PATCH] Replace TyDesc and its uses with trait vtables and a type_name intrinsic. --- src/libarena/lib.rs | 24 +++- src/libcore/intrinsics.rs | 7 + src/librustc/middle/lang_items.rs | 3 - src/librustc/middle/ty.rs | 12 +- src/librustc_trans/trans/base.rs | 22 +-- src/librustc_trans/trans/common.rs | 9 -- src/librustc_trans/trans/context.rs | 24 +--- src/librustc_trans/trans/glue.rs | 187 ++++++-------------------- src/librustc_trans/trans/intrinsic.rs | 11 +- src/librustc_trans/trans/machine.rs | 14 +- src/librustc_trans/trans/type_.rs | 31 ----- src/librustc_typeck/check/mod.rs | 13 +- src/librustc_typeck/collect.rs | 18 --- src/test/run-pass/issue-21058.rs | 12 +- src/test/run-pass/tydesc-name.rs | 6 +- 15 files changed, 87 insertions(+), 306 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index 029d9d03835e8..fb858344b85d5 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -42,8 +42,9 @@ extern crate alloc; use std::cell::{Cell, RefCell}; use std::cmp; -use std::intrinsics::{TyDesc, get_tydesc}; use std::intrinsics; +#[cfg(stage0)] // SNAP 270a677 +use std::intrinsics::{get_tydesc, TyDesc}; use std::marker; use std::mem; #[cfg(stage0)] @@ -186,6 +187,27 @@ fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) { ((p & !1) as *const TyDesc, p & 1 == 1) } +// HACK(eddyb) TyDesc replacement using a trait object vtable. +// This could be replaced in the future with a custom DST layout, +// or `&'static (drop_glue, size, align)` created by a `const fn`. +#[cfg(not(stage0))] // SNAP 270a677 +struct TyDesc { + drop_glue: fn(*const i8), + size: usize, + align: usize +} + +#[cfg(not(stage0))] // SNAP 270a677 +unsafe fn get_tydesc() -> *const TyDesc { + use std::raw::TraitObject; + + let ptr = &*(1 as *const T); + + // Can use any trait that is implemented for all types. + let obj = mem::transmute::<&marker::MarkerTrait, TraitObject>(ptr); + obj.vtable as *const TyDesc +} + impl<'longer_than_self> Arena<'longer_than_self> { fn chunk_size(&self) -> usize { self.copy_head.borrow().capacity() diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index 7fccb93f2a002..ead5da92bd901 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -44,10 +44,12 @@ use marker::Sized; +#[cfg(stage0)] // SNAP 270a677 pub type GlueFn = extern "Rust" fn(*const i8); #[lang="ty_desc"] #[derive(Copy)] +#[cfg(stage0)] // SNAP 270a677 pub struct TyDesc { // sizeof(T) pub size: usize, @@ -197,8 +199,13 @@ extern "rust-intrinsic" { pub fn pref_align_of() -> usize; /// Get a static pointer to a type descriptor. + #[cfg(stage0)] // SNAP 270a677 pub fn get_tydesc() -> *const TyDesc; + /// Gets a static string slice containing the name of a type. + #[cfg(not(stage0))] // SNAP 270a677 + pub fn type_name() -> &'static str; + /// Gets an identifier which is globally unique to the specified type. This /// function will return the same value for a type regardless of whichever /// crate it is invoked in. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 1ad4611dc9ee3..73d31a1f6201d 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -316,9 +316,6 @@ lets_do_this! { StartFnLangItem, "start", start_fn; - TyDescStructLangItem, "ty_desc", ty_desc; - OpaqueStructLangItem, "opaque", opaque; - EhPersonalityLangItem, "eh_personality", eh_personality; ExchangeHeapLangItem, "exchange_heap", exchange_heap; diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8cc188e5df5b0..3d70d95ef1476 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -47,8 +47,7 @@ use middle::check_const; use middle::const_eval; use middle::def::{self, DefMap, ExportMap}; use middle::dependency_format; -use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem}; -use middle::lang_items::{FnOnceTraitLangItem, TyDescStructLangItem}; +use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::mem_categorization as mc; use middle::region; use middle::resolve_lifetime; @@ -723,7 +722,6 @@ pub struct ctxt<'tcx> { pub object_cast_map: ObjectCastMap<'tcx>, pub map: ast_map::Map<'tcx>, - pub intrinsic_defs: RefCell>>, pub freevars: RefCell, pub tcache: RefCell>>, pub rcache: RefCell>>, @@ -2575,7 +2573,6 @@ pub fn mk_ctxt<'tcx>(s: Session, super_predicates: RefCell::new(DefIdMap()), object_cast_map: RefCell::new(NodeMap()), map: map, - intrinsic_defs: RefCell::new(DefIdMap()), freevars: freevars, tcache: RefCell::new(DefIdMap()), rcache: RefCell::new(FnvHashMap()), @@ -5951,13 +5948,6 @@ pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>, .collect() } -pub fn get_tydesc_ty<'tcx>(tcx: &ctxt<'tcx>) -> Result, String> { - tcx.lang_items.require(TyDescStructLangItem).map(|tydesc_lang_item| { - tcx.intrinsic_defs.borrow().get(&tydesc_lang_item).cloned() - .expect("Failed to resolve TyDesc") - }) -} - pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc { lookup_locally_or_in_crate_store( "item_variance_map", item_id, &mut *tcx.item_variance_map.borrow_mut(), diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 3e0df733e9d15..5f2803835d5d3 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -57,8 +57,7 @@ use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef}; use trans::common::{CrateContext, ExternMap, FunctionContext}; use trans::common::{Result, NodeIdAndSpan}; use trans::common::{node_id_type, return_type_is_void}; -use trans::common::{tydesc_info, type_is_immediate}; -use trans::common::{type_is_zero_size, val_ty}; +use trans::common::{type_is_immediate, type_is_zero_size, val_ty}; use trans::common; use trans::consts; use trans::context::SharedCrateContext; @@ -90,7 +89,6 @@ use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; use std::collections::HashSet; use std::mem; -use std::rc::Rc; use std::str; use std::{i8, i16, i32, i64}; use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi}; @@ -392,22 +390,6 @@ pub fn malloc_raw_dyn<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, Result::new(r.bcx, PointerCast(r.bcx, r.val, llty_ptr)) } -// Type descriptor and type glue stuff - -pub fn get_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - t: Ty<'tcx>) -> Rc> { - match ccx.tydescs().borrow().get(&t) { - Some(inf) => return inf.clone(), - _ => { } - } - - ccx.stats().n_static_tydescs.set(ccx.stats().n_static_tydescs.get() + 1); - let inf = Rc::new(glue::declare_tydesc(ccx, t)); - - ccx.tydescs().borrow_mut().insert(t, inf.clone()); - inf -} - #[allow(dead_code)] // useful pub fn set_optimize_for_size(f: ValueRef) { llvm::SetFunctionAttribute(f, llvm::OptimizeForSizeAttribute) @@ -3137,7 +3119,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) } for ccx in shared_ccx.iter() { - glue::emit_tydescs(&ccx); if ccx.sess().opts.debuginfo != NoDebugInfo { debuginfo::finalize(&ccx); } @@ -3149,7 +3130,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>) if shared_ccx.sess().trans_stats() { let stats = shared_ccx.stats(); println!("--- trans stats ---"); - println!("n_static_tydescs: {}", stats.n_static_tydescs.get()); println!("n_glues_created: {}", stats.n_glues_created.get()); println!("n_null_glues: {}", stats.n_null_glues.get()); println!("n_real_glues: {}", stats.n_real_glues.get()); diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index ec7ed2fe89017..941ac5d627f3b 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -316,15 +316,6 @@ pub fn gensym_name(name: &str) -> PathElem { PathName(token::gensym(&format!("{}:{}", name, num))) } -#[derive(Copy)] -pub struct tydesc_info<'tcx> { - pub ty: Ty<'tcx>, - pub tydesc: ValueRef, - pub size: ValueRef, - pub align: ValueRef, - pub name: ValueRef, -} - /* * A note on nomenclature of linking: "extern", "foreign", and "upcall". * diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs index da04768ee06e1..6614d538971dd 100644 --- a/src/librustc_trans/trans/context.rs +++ b/src/librustc_trans/trans/context.rs @@ -18,7 +18,7 @@ use middle::traits; use trans::adt; use trans::base; use trans::builder::Builder; -use trans::common::{ExternMap,tydesc_info,BuilderRef_res}; +use trans::common::{ExternMap,BuilderRef_res}; use trans::debuginfo; use trans::monomorphize::MonoId; use trans::type_::{Type, TypeNames}; @@ -38,7 +38,6 @@ use syntax::ast; use syntax::parse::token::InternedString; pub struct Stats { - pub n_static_tydescs: Cell, pub n_glues_created: Cell, pub n_null_glues: Cell, pub n_real_glues: Cell, @@ -89,10 +88,6 @@ pub struct LocalCrateContext<'tcx> { needs_unwind_cleanup_cache: RefCell, bool>>, fn_pointer_shims: RefCell, ValueRef>>, drop_glues: RefCell, ValueRef>>, - tydescs: RefCell, Rc>>>, - /// Set when running emit_tydescs to enforce that no more tydescs are - /// created. - finished_tydescs: Cell, /// Track mapping of external ids to local items imported for inlining external: RefCell>>, /// Backwards version of the `external` map (inlined items to where they @@ -264,7 +259,6 @@ impl<'tcx> SharedCrateContext<'tcx> { symbol_hasher: RefCell::new(symbol_hasher), tcx: tcx, stats: Stats { - n_static_tydescs: Cell::new(0), n_glues_created: Cell::new(0), n_null_glues: Cell::new(0), n_real_glues: Cell::new(0), @@ -399,8 +393,6 @@ impl<'tcx> LocalCrateContext<'tcx> { needs_unwind_cleanup_cache: RefCell::new(FnvHashMap()), fn_pointer_shims: RefCell::new(FnvHashMap()), drop_glues: RefCell::new(FnvHashMap()), - tydescs: RefCell::new(FnvHashMap()), - finished_tydescs: Cell::new(false), external: RefCell::new(DefIdMap()), external_srcs: RefCell::new(NodeMap()), monomorphized: RefCell::new(FnvHashMap()), @@ -442,8 +434,6 @@ impl<'tcx> LocalCrateContext<'tcx> { str_slice_ty.set_struct_body(&[Type::i8p(&ccx), ccx.int_type()], false); ccx.tn().associate_type("str_slice", &str_slice_ty); - ccx.tn().associate_type("tydesc", &Type::tydesc(&ccx, str_slice_ty)); - if ccx.sess().count_llvm_insns() { base::init_insn_ctxt() } @@ -519,10 +509,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { self.local.builder.b } - pub fn tydesc_type(&self) -> Type { - self.local.tn.find_type("tydesc").unwrap() - } - pub fn get_intrinsic(&self, key: & &'static str) -> ValueRef { if let Some(v) = self.intrinsics().borrow().get(key).cloned() { return v; @@ -590,14 +576,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> { &self.local.drop_glues } - pub fn tydescs<'a>(&'a self) -> &'a RefCell, Rc>>> { - &self.local.tydescs - } - - pub fn finished_tydescs<'a>(&'a self) -> &'a Cell { - &self.local.finished_tydescs - } - pub fn external<'a>(&'a self) -> &'a RefCell>> { &self.local.external } diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs index a9375ebe57d59..b2de8435f641b 100644 --- a/src/librustc_trans/trans/glue.rs +++ b/src/librustc_trans/trans/glue.rs @@ -10,12 +10,12 @@ //! // -// Code relating to taking, dropping, etc as well as type descriptors. +// Code relating to drop glue. use back::abi; use back::link::*; -use llvm::{ValueRef, True, get_param}; +use llvm::{ValueRef, get_param}; use llvm; use middle::lang_items::ExchangeFreeFnLangItem; use middle::subst; @@ -26,23 +26,20 @@ use trans::build::*; use trans::callee; use trans::cleanup; use trans::cleanup::CleanupMethods; -use trans::consts; use trans::common::*; use trans::datum; use trans::debuginfo::DebugLoc; use trans::expr; use trans::machine::*; use trans::type_::Type; -use trans::type_of::{self, type_of, sizing_type_of, align_of}; +use trans::type_of::{type_of, sizing_type_of, align_of}; use middle::ty::{self, Ty}; use util::ppaux::{ty_to_short_str, Repr}; use util::ppaux; use arena::TypedArena; use libc::c_uint; -use std::ffi::CString; use syntax::ast; -use syntax::parse::token; pub fn trans_exchange_free_dyn<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, @@ -177,31 +174,46 @@ pub fn get_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Val let llfnty = Type::glue_fn(ccx, llty); - let (glue, new_sym) = match ccx.available_drop_glues().borrow().get(&t) { - Some(old_sym) => { - let glue = decl_cdecl_fn(ccx, &old_sym[..], llfnty, ty::mk_nil(ccx.tcx())); - (glue, None) - }, - None => { - let (sym, glue) = declare_generic_glue(ccx, t, llfnty, "drop"); - (glue, Some(sym)) - }, + // To avoid infinite recursion, don't `make_drop_glue` until after we've + // added the entry to the `drop_glues` cache. + if let Some(old_sym) = ccx.available_drop_glues().borrow().get(&t) { + let llfn = decl_cdecl_fn(ccx, &old_sym, llfnty, ty::mk_nil(ccx.tcx())); + ccx.drop_glues().borrow_mut().insert(t, llfn); + return llfn; }; - ccx.drop_glues().borrow_mut().insert(t, glue); + let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, "drop"); + let llfn = decl_cdecl_fn(ccx, &fn_nm, llfnty, ty::mk_nil(ccx.tcx())); + note_unique_llvm_symbol(ccx, fn_nm.clone()); + ccx.available_drop_glues().borrow_mut().insert(t, fn_nm); - // To avoid infinite recursion, don't `make_drop_glue` until after we've - // added the entry to the `drop_glues` cache. - match new_sym { - Some(sym) => { - ccx.available_drop_glues().borrow_mut().insert(t, sym); - // We're creating a new drop glue, so also generate a body. - make_generic_glue(ccx, t, glue, make_drop_glue, "drop"); - }, - None => {}, - } + let _s = StatRecorder::new(ccx, format!("drop {}", ty_to_short_str(ccx.tcx(), t))); + + let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); + let (arena, fcx): (TypedArena<_>, FunctionContext); + arena = TypedArena::new(); + fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, + ty::FnConverging(ty::mk_nil(ccx.tcx())), + empty_substs, None, &arena); + + let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil(ccx.tcx()))); + + update_linkage(ccx, llfn, None, OriginalTranslation); + + ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1); + // All glue functions take values passed *by alias*; this is a + // requirement since in many contexts glue is invoked indirectly and + // the caller has no idea if it's dealing with something that can be + // passed by value. + // + // llfn is expected be declared to take a parameter of the appropriate + // type, so we don't need to explicitly cast the function parameter. + + let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint); + let bcx = make_drop_glue(bcx, llrawptr0, t); + finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None); - glue + llfn } fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, @@ -467,124 +479,3 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>) } } } - -// Generates the declaration for (but doesn't emit) a type descriptor. -pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) - -> tydesc_info<'tcx> { - // If emit_tydescs already ran, then we shouldn't be creating any new - // tydescs. - assert!(!ccx.finished_tydescs().get()); - - // This really shouldn't be like this, size/align will be wrong for - // unsized types (i.e. [T] will have the size/align of T). - // But we need it until we split this out into a "type name" intrinsic. - let llty = type_of::in_memory_type_of(ccx, t); - - if ccx.sess().count_type_sizes() { - println!("{}\t{}", llsize_of_real(ccx, llty), - ppaux::ty_to_string(ccx.tcx(), t)); - } - - let llsize = llsize_of(ccx, llty); - let llalign = llalign_of(ccx, llty); - let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc"); - debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name); - let buf = CString::new(name.clone()).unwrap(); - let gvar = unsafe { - llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(), - buf.as_ptr()) - }; - note_unique_llvm_symbol(ccx, name); - - let ty_name = token::intern_and_get_ident( - &ppaux::ty_to_string(ccx.tcx(), t)); - let ty_name = C_str_slice(ccx, ty_name); - - debug!("--- declare_tydesc {}", ppaux::ty_to_string(ccx.tcx(), t)); - tydesc_info { - ty: t, - tydesc: gvar, - size: llsize, - align: llalign, - name: ty_name, - } -} - -fn declare_generic_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>, - llfnty: Type, name: &str) -> (String, ValueRef) { - let _icx = push_ctxt("declare_generic_glue"); - let fn_nm = mangle_internal_name_by_type_and_seq( - ccx, - t, - &format!("glue_{}", name)); - let llfn = decl_cdecl_fn(ccx, &fn_nm[..], llfnty, ty::mk_nil(ccx.tcx())); - note_unique_llvm_symbol(ccx, fn_nm.clone()); - return (fn_nm, llfn); -} - -fn make_generic_glue<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>, - t: Ty<'tcx>, - llfn: ValueRef, - helper: F, - name: &str) - -> ValueRef where - F: for<'blk> FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>, -{ - let _icx = push_ctxt("make_generic_glue"); - let glue_name = format!("glue {} {}", name, ty_to_short_str(ccx.tcx(), t)); - let _s = StatRecorder::new(ccx, glue_name); - - let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty()); - let (arena, fcx): (TypedArena<_>, FunctionContext); - arena = TypedArena::new(); - fcx = new_fn_ctxt(ccx, llfn, ast::DUMMY_NODE_ID, false, - ty::FnConverging(ty::mk_nil(ccx.tcx())), - empty_substs, None, &arena); - - let bcx = init_function(&fcx, false, ty::FnConverging(ty::mk_nil(ccx.tcx()))); - - update_linkage(ccx, llfn, None, OriginalTranslation); - - ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1); - // All glue functions take values passed *by alias*; this is a - // requirement since in many contexts glue is invoked indirectly and - // the caller has no idea if it's dealing with something that can be - // passed by value. - // - // llfn is expected be declared to take a parameter of the appropriate - // type, so we don't need to explicitly cast the function parameter. - - let llrawptr0 = get_param(llfn, fcx.arg_pos(0) as c_uint); - let bcx = helper(bcx, llrawptr0, t); - finish_fn(&fcx, bcx, ty::FnConverging(ty::mk_nil(ccx.tcx())), DebugLoc::None); - - llfn -} - -pub fn emit_tydescs(ccx: &CrateContext) { - let _icx = push_ctxt("emit_tydescs"); - // As of this point, allow no more tydescs to be created. - ccx.finished_tydescs().set(true); - let glue_fn_ty = Type::generic_glue_fn(ccx).ptr_to(); - for (_, ti) in &*ccx.tydescs().borrow() { - // Each of the glue functions needs to be cast to a generic type - // before being put into the tydesc because we only have a singleton - // tydesc type. Then we'll recast each function to its real type when - // calling it. - let drop_glue = consts::ptrcast(get_drop_glue(ccx, ti.ty), glue_fn_ty); - ccx.stats().n_real_glues.set(ccx.stats().n_real_glues.get() + 1); - - let tydesc = C_named_struct(ccx.tydesc_type(), - &[ti.size, // size - ti.align, // align - drop_glue, // drop_glue - ti.name]); // name - - unsafe { - let gvar = ti.tydesc; - llvm::LLVMSetInitializer(gvar, tydesc); - llvm::LLVMSetGlobalConstant(gvar, True); - llvm::SetLinkage(gvar, llvm::InternalLinkage); - } - }; -} diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 916492195c258..69ca9a5e81cbc 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -347,15 +347,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, bcx = src.store_to(bcx, llargs[0]); C_nil(ccx) } - (_, "get_tydesc") => { + (_, "type_name") => { let tp_ty = *substs.types.get(FnSpace, 0); - let static_ti = get_tydesc(ccx, tp_ty); - - // FIXME (#3730): ideally this shouldn't need a cast, - // but there's a circularity between translating rust types to llvm - // types and having a tydesc type available. So I can't directly access - // the llvm type of intrinsic::TyDesc struct. - PointerCast(bcx, static_ti.tydesc, llret_ty) + let ty_name = token::intern_and_get_ident(&ty_to_string(ccx.tcx(), tp_ty)); + C_str_slice(ccx, ty_name) } (_, "type_id") => { let hash = ty::hash_crate_independent( diff --git a/src/librustc_trans/trans/machine.rs b/src/librustc_trans/trans/machine.rs index 1552ac0bea0fe..9b17c4f8baac9 100644 --- a/src/librustc_trans/trans/machine.rs +++ b/src/librustc_trans/trans/machine.rs @@ -12,9 +12,7 @@ #![allow(non_camel_case_types)] -use llvm; -use llvm::{ValueRef}; -use llvm::False; +use llvm::{self, ValueRef}; use trans::common::*; use trans::type_::Type; @@ -101,16 +99,6 @@ pub fn llalign_of_min(cx: &CrateContext, ty: Type) -> llalign { } } -// Returns the "default" alignment of t, which is calculated by casting -// null to a record containing a single-bit followed by a t value, then -// doing gep(0,1) to get at the trailing (and presumably padded) t cell. -pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef { - unsafe { - return llvm::LLVMConstIntCast( - llvm::LLVMAlignOf(ty.to_ref()), cx.int_type().to_ref(), False); - } -} - pub fn llelement_offset(cx: &CrateContext, struct_ty: Type, element: uint) -> u64 { unsafe { return llvm::LLVMOffsetOfElement(cx.td().lltd, struct_ty.to_ref(), diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index d5ec18e641b79..dcb57fd9cdebd 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -175,41 +175,10 @@ impl Type { Type::array(&Type::i8p(ccx).ptr_to(), 1) } - pub fn generic_glue_fn(cx: &CrateContext) -> Type { - match cx.tn().find_type("glue_fn") { - Some(ty) => return ty, - None => () - } - - let ty = Type::glue_fn(cx, Type::i8p(cx)); - cx.tn().associate_type("glue_fn", &ty); - - ty - } - pub fn glue_fn(ccx: &CrateContext, t: Type) -> Type { Type::func(&[t], &Type::void(ccx)) } - pub fn tydesc(ccx: &CrateContext, str_slice_ty: Type) -> Type { - let mut tydesc = Type::named_struct(ccx, "tydesc"); - let glue_fn_ty = Type::glue_fn(ccx, Type::i8p(ccx)).ptr_to(); - - let int_ty = Type::int(ccx); - - // Must mirror: - // - // std::unstable::intrinsics::TyDesc - - let elems = [int_ty, // size - int_ty, // align - glue_fn_ty, // drop - str_slice_ty]; // name - tydesc.set_struct_body(&elems, false); - - tydesc - } - pub fn array(ty: &Type, len: u64) -> Type { ty!(llvm::LLVMRustArrayType(ty.to_ref(), len)) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 31bee612b78d4..de0978bc40957 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5347,17 +5347,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "needs_drop" => (1, Vec::new(), ccx.tcx.types.bool), "owns_managed" => (1, Vec::new(), ccx.tcx.types.bool), - "get_tydesc" => { - let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) { - Ok(t) => t, - Err(s) => { span_fatal!(tcx.sess, it.span, E0240, "{}", &s[..]); } - }; - let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { - ty: tydesc_ty, - mutbl: ast::MutImmutable - }); - (1, Vec::new(), td_ptr) - } + "type_name" => (1, Vec::new(), ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic), + ast::MutImmutable)), "type_id" => (1, Vec::new(), ccx.tcx.types.u64), "offset" => { (1, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 2372680576797..97cc3ac7c48a7 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -102,15 +102,6 @@ use syntax::visit; pub fn collect_item_types(tcx: &ty::ctxt) { let ccx = &CrateCtxt { tcx: tcx, stack: RefCell::new(Vec::new()) }; - match ccx.tcx.lang_items.ty_desc() { - Some(id) => { collect_intrinsic_type(ccx, id); } - None => {} - } - match ccx.tcx.lang_items.opaque() { - Some(id) => { collect_intrinsic_type(ccx, id); } - None => {} - } - let mut visitor = CollectTraitDefVisitor{ ccx: ccx }; visit::walk_crate(&mut visitor, ccx.tcx.map.krate()); @@ -152,15 +143,6 @@ enum AstConvRequest { GetTypeParameterBounds(ast::NodeId), } -/////////////////////////////////////////////////////////////////////////// -// Zeroth phase: collect types of intrinsics - -fn collect_intrinsic_type(ccx: &CrateCtxt, - lang_item: ast::DefId) { - let ty::TypeScheme { ty, .. } = type_scheme_of_def_id(ccx, lang_item); - ccx.tcx.intrinsic_defs.borrow_mut().insert(lang_item, ty); -} - /////////////////////////////////////////////////////////////////////////// // First phase: just collect *trait definitions* -- basically, the set // of type parameters and supertraits. This is information we need to diff --git a/src/test/run-pass/issue-21058.rs b/src/test/run-pass/issue-21058.rs index 3cdd57aed5a1c..e53fe3c44a28e 100644 --- a/src/test/run-pass/issue-21058.rs +++ b/src/test/run-pass/issue-21058.rs @@ -13,17 +13,17 @@ struct NT(str); struct DST { a: u32, b: str } fn main() { - // get_tydesc should support unsized types + // type_name should support unsized types assert_eq!(unsafe {( // Slice - (*std::intrinsics::get_tydesc::<[u8]>()).name, + std::intrinsics::type_name::<[u8]>(), // str - (*std::intrinsics::get_tydesc::()).name, + std::intrinsics::type_name::(), // Trait - (*std::intrinsics::get_tydesc::()).name, + std::intrinsics::type_name::(), // Newtype - (*std::intrinsics::get_tydesc::()).name, + std::intrinsics::type_name::(), // DST - (*std::intrinsics::get_tydesc::()).name + std::intrinsics::type_name::() )}, ("[u8]", "str", "core::marker::Copy", "NT", "DST")); } diff --git a/src/test/run-pass/tydesc-name.rs b/src/test/run-pass/tydesc-name.rs index e3b148ac92db6..2e7717fcfe154 100644 --- a/src/test/run-pass/tydesc-name.rs +++ b/src/test/run-pass/tydesc-name.rs @@ -9,7 +9,7 @@ // except according to those terms. -use std::intrinsics::get_tydesc; +use std::intrinsics::type_name; struct Foo { x: T @@ -17,7 +17,7 @@ struct Foo { pub fn main() { unsafe { - assert_eq!((*get_tydesc::()).name, "isize"); - assert_eq!((*get_tydesc::>()).name, "Foo"); + assert_eq!(type_name::(), "isize"); + assert_eq!(type_name::>(), "Foo"); } }