about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-03-17 21:23:02 +0000
committerbors <bors@rust-lang.org>2015-03-17 21:23:02 +0000
commitea8b82e90c450febb1f26a07862a1ec89c22addd (patch)
treeba4c1da25278a56c52803f1b49c844b7a91b5b90
parentbfac337daab9b86971bcb3db61382ac44f94621c (diff)
parente256b7f049b44fa697b9f9c5e75b4433a7d9ffdf (diff)
downloadrust-ea8b82e90c450febb1f26a07862a1ec89c22addd.tar.gz
rust-ea8b82e90c450febb1f26a07862a1ec89c22addd.zip
Auto merge of #23376 - eddyb:die-tydesc-die, r=nikomatsakis
Final remnant of reflection is gone. Also, virtual `Trait` destructors are no longer tied to `Box`.
That means they can be used to drop any instance of the type (used in libarena to replace TyDesc).

This is [breaking-change] for direct users of intrinsics:
* use `intrinsics::type_name::<T>()` instead of `(*intrinsics::get_tydesc::<T>()).name`
* the only way to get the destructor is from a trait object's vtable (see libarena changes)

r? @pcwalton f? @dotdash
-rw-r--r--src/libarena/lib.rs24
-rw-r--r--src/libcore/intrinsics.rs7
-rw-r--r--src/librustc/middle/lang_items.rs3
-rw-r--r--src/librustc/middle/ty.rs12
-rw-r--r--src/librustc_trans/trans/_match.rs4
-rw-r--r--src/librustc_trans/trans/base.rs26
-rw-r--r--src/librustc_trans/trans/common.rs9
-rw-r--r--src/librustc_trans/trans/consts.rs1
-rw-r--r--src/librustc_trans/trans/context.rs29
-rw-r--r--src/librustc_trans/trans/expr.rs55
-rw-r--r--src/librustc_trans/trans/glue.rs284
-rw-r--r--src/librustc_trans/trans/intrinsic.rs11
-rw-r--r--src/librustc_trans/trans/machine.rs14
-rw-r--r--src/librustc_trans/trans/meth.rs23
-rw-r--r--src/librustc_trans/trans/tvec.rs123
-rw-r--r--src/librustc_trans/trans/type_.rs31
-rw-r--r--src/librustc_typeck/check/mod.rs13
-rw-r--r--src/librustc_typeck/collect.rs18
-rw-r--r--src/test/run-pass/issue-21058.rs12
-rw-r--r--src/test/run-pass/tydesc-name.rs6
20 files changed, 177 insertions, 528 deletions
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 029d9d03835..fb858344b85 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<T>() -> *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 7fccb93f2a0..ead5da92bd9 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<T>() -> usize;
 
     /// Get a static pointer to a type descriptor.
+    #[cfg(stage0)] // SNAP 270a677
     pub fn get_tydesc<T: ?Sized>() -> *const TyDesc;
 
+    /// Gets a static string slice containing the name of a type.
+    #[cfg(not(stage0))] // SNAP 270a677
+    pub fn type_name<T: ?Sized>() -> &'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 1ad4611dc9e..73d31a1f620 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 8cc188e5df5..3d70d95ef14 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<DefIdMap<Ty<'tcx>>>,
     pub freevars: RefCell<FreevarMap>,
     pub tcache: RefCell<DefIdMap<TypeScheme<'tcx>>>,
     pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
@@ -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<Ty<'tcx>, 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<ItemVariances> {
     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/_match.rs b/src/librustc_trans/trans/_match.rs
index 2ab6f5b0f95..bd9313ee9b0 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -660,7 +660,7 @@ fn bind_subslice_pat(bcx: Block,
                      offset_right: uint) -> ValueRef {
     let _icx = push_ctxt("match::bind_subslice_pat");
     let vec_ty = node_id_type(bcx, pat_id);
-    let vt = tvec::vec_types(bcx, ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty)));
+    let unit_ty = ty::sequence_element_type(bcx.tcx(), ty::type_content(vec_ty));
     let vec_datum = match_datum(val, vec_ty);
     let (base, len) = vec_datum.get_vec_base_and_len(bcx);
 
@@ -669,7 +669,7 @@ fn bind_subslice_pat(bcx: Block,
     let slice_len = Sub(bcx, len, slice_len_offset, DebugLoc::None);
     let slice_ty = ty::mk_slice(bcx.tcx(),
                                 bcx.tcx().mk_region(ty::ReStatic),
-                                ty::mt {ty: vt.unit_ty, mutbl: ast::MutImmutable});
+                                ty::mt {ty: unit_ty, mutbl: ast::MutImmutable});
     let scratch = rvalue_scratch_datum(bcx, slice_ty, "");
     Store(bcx, slice_begin,
           GEPi(bcx, scratch.val, &[0, abi::FAT_PTR_ADDR]));
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index e9f58ec53df..5f2803835d5 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<tydesc_info<'tcx>> {
-    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)
@@ -702,6 +684,10 @@ pub fn iter_structural_ty<'blk, 'tcx, F>(cx: Block<'blk, 'tcx>,
         let unit_ty = ty::sequence_element_type(cx.tcx(), t);
         cx = tvec::iter_vec_raw(cx, base, unit_ty, len, f);
       }
+      ty::ty_vec(_, None) | ty::ty_str => {
+        let unit_ty = ty::sequence_element_type(cx.tcx(), t);
+        cx = tvec::iter_vec_raw(cx, data_ptr, unit_ty, info.unwrap(), f);
+      }
       ty::ty_tup(ref args) => {
           let repr = adt::represent_type(cx.ccx(), t);
           for (i, arg) in args.iter().enumerate() {
@@ -3133,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);
         }
@@ -3145,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 ec7ed2fe890..941ac5d627f 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/consts.rs b/src/librustc_trans/trans/consts.rs
index 6ff230b7065..9d2b20f288a 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -314,7 +314,6 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                     let info =
                         expr::unsized_info(
                             cx, k, e.id, ty, param_substs,
-                            |t| ty::mk_imm_rptr(cx.tcx(), cx.tcx().mk_region(ty::ReStatic), t),
                             || const_get_elt(cx, llconst, &[abi::FAT_PTR_EXTRA as u32]));
 
                     let unsized_ty = ty::unsize_ty(cx.tcx(), ty, k, e.span);
diff --git a/src/librustc_trans/trans/context.rs b/src/librustc_trans/trans/context.rs
index 9777398bddc..6614d538971 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<uint>,
     pub n_glues_created: Cell<uint>,
     pub n_null_glues: Cell<uint>,
     pub n_real_glues: Cell<uint>,
@@ -89,10 +88,6 @@ pub struct LocalCrateContext<'tcx> {
     needs_unwind_cleanup_cache: RefCell<FnvHashMap<Ty<'tcx>, bool>>,
     fn_pointer_shims: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
     drop_glues: RefCell<FnvHashMap<Ty<'tcx>, ValueRef>>,
-    tydescs: RefCell<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>>,
-    /// Set when running emit_tydescs to enforce that no more tydescs are
-    /// created.
-    finished_tydescs: Cell<bool>,
     /// Track mapping of external ids to local items imported for inlining
     external: RefCell<DefIdMap<Option<ast::NodeId>>>,
     /// Backwards version of the `external` map (inlined items to where they
@@ -102,7 +97,7 @@ pub struct LocalCrateContext<'tcx> {
     monomorphized: RefCell<FnvHashMap<MonoId<'tcx>, ValueRef>>,
     monomorphizing: RefCell<DefIdMap<uint>>,
     /// Cache generated vtables
-    vtables: RefCell<FnvHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>), ValueRef>>,
+    vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
     /// Cache of constant strings,
     const_cstr_cache: RefCell<FnvHashMap<InternedString, ValueRef>>,
 
@@ -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<FnvHashMap<Ty<'tcx>, Rc<tydesc_info<'tcx>>>> {
-        &self.local.tydescs
-    }
-
-    pub fn finished_tydescs<'a>(&'a self) -> &'a Cell<bool> {
-        &self.local.finished_tydescs
-    }
-
     pub fn external<'a>(&'a self) -> &'a RefCell<DefIdMap<Option<ast::NodeId>>> {
         &self.local.external
     }
@@ -614,8 +592,7 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local.monomorphizing
     }
 
-    pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<(Ty<'tcx>, ty::PolyTraitRef<'tcx>),
-                                                            ValueRef>> {
+    pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>> {
         &self.local.vtables
     }
 
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index da2b5a43b48..6de67754f11 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -288,53 +288,38 @@ pub fn get_dataptr(bcx: Block, fat_ptr: ValueRef) -> ValueRef {
 // Retrieve the information we are losing (making dynamic) in an unsizing
 // adjustment.
 //
-// When making a dtor, we need to do different things depending on the
-// ownership of the object.. mk_ty is a function for turning `unadjusted_ty`
-// into a type to be destructed. If we want to end up with a Box pointer,
-// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
-// borrowed reference then it should be T -> &T.
-//
 // The `unadjusted_val` argument is a bit funny. It is intended
 // for use in an upcast, where the new vtable for an object will
 // be drived from the old one. Hence it is a pointer to the fat
 // pointer.
-pub fn unsized_info_bcx<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
-                                       kind: &ty::UnsizeKind<'tcx>,
-                                       id: ast::NodeId,
-                                       unadjusted_ty: Ty<'tcx>,
-                                       unadjusted_val: ValueRef, // see above (*)
-                                       param_substs: &'tcx subst::Substs<'tcx>,
-                                       mk_ty: F)
-                                       -> ValueRef
-    where F: FnOnce(Ty<'tcx>) -> Ty<'tcx>
-{
+pub fn unsized_info_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                    kind: &ty::UnsizeKind<'tcx>,
+                                    id: ast::NodeId,
+                                    unadjusted_ty: Ty<'tcx>,
+                                    unadjusted_val: ValueRef, // see above (*)
+                                    param_substs: &'tcx subst::Substs<'tcx>)
+                                    -> ValueRef {
     unsized_info(
         bcx.ccx(),
         kind,
         id,
         unadjusted_ty,
         param_substs,
-        mk_ty,
         || Load(bcx, GEPi(bcx, unadjusted_val, &[0, abi::FAT_PTR_EXTRA])))
 }
 
 // Same as `unsize_info_bcx`, but does not require a bcx -- instead it
 // takes an extra closure to compute the upcast vtable.
-pub fn unsized_info<'ccx, 'tcx, MK_TY, MK_UPCAST_VTABLE>(
+pub fn unsized_info<'ccx, 'tcx, MK_UPCAST_VTABLE>(
     ccx: &CrateContext<'ccx, 'tcx>,
     kind: &ty::UnsizeKind<'tcx>,
     id: ast::NodeId,
     unadjusted_ty: Ty<'tcx>,
     param_substs: &'tcx subst::Substs<'tcx>,
-    mk_ty: MK_TY,
     mk_upcast_vtable: MK_UPCAST_VTABLE) // see notes above
     -> ValueRef
-    where MK_TY: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
-          MK_UPCAST_VTABLE: FnOnce() -> ValueRef,
+    where MK_UPCAST_VTABLE: FnOnce() -> ValueRef
 {
-    // FIXME(#19596) workaround: `|t| t` causes monomorphization recursion
-    fn identity<T>(t: T) -> T { t }
-
     debug!("unsized_info(kind={:?}, id={}, unadjusted_ty={})",
            kind, id, unadjusted_ty.repr(ccx.tcx()));
     match kind {
@@ -342,10 +327,8 @@ pub fn unsized_info<'ccx, 'tcx, MK_TY, MK_UPCAST_VTABLE>(
         &ty::UnsizeStruct(box ref k, tp_index) => match unadjusted_ty.sty {
             ty::ty_struct(_, ref substs) => {
                 let ty_substs = substs.types.get_slice(subst::TypeSpace);
-                // The dtor for a field treats it like a value, so mk_ty
-                // should just be the identity function.
                 unsized_info(ccx, k, id, ty_substs[tp_index], param_substs,
-                             identity, mk_upcast_vtable)
+                             mk_upcast_vtable)
             }
             _ => ccx.sess().bug(&format!("UnsizeStruct with bad sty: {}",
                                          unadjusted_ty.repr(ccx.tcx())))
@@ -359,8 +342,7 @@ pub fn unsized_info<'ccx, 'tcx, MK_TY, MK_UPCAST_VTABLE>(
             let trait_ref = monomorphize::apply_param_substs(ccx.tcx(),
                                                              param_substs,
                                                              &trait_ref);
-            let box_ty = mk_ty(unadjusted_ty);
-            consts::ptrcast(meth::get_vtable(ccx, box_ty, trait_ref, param_substs),
+            consts::ptrcast(meth::get_vtable(ccx, trait_ref, param_substs),
                             Type::vtable_ptr(ccx))
         }
         &ty::UnsizeUpcast(_) => {
@@ -498,8 +480,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span);
         debug!("unsized_ty={}", unsized_ty.repr(bcx.tcx()));
 
-        let info = unsized_info_bcx(bcx, k, expr.id, datum_ty, datum.val, bcx.fcx.param_substs,
-                                    |t| ty::mk_imm_rptr(tcx, tcx.mk_region(ty::ReStatic), t));
+        let info = unsized_info_bcx(bcx, k, expr.id, datum_ty, datum.val, bcx.fcx.param_substs);
 
         // Arrange cleanup
         let lval = unpack_datum!(bcx, datum.to_lvalue_datum(bcx, "into_fat_ptr", expr.id));
@@ -590,8 +571,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         let base = PointerCast(bcx, get_dataptr(bcx, scratch.val), llbox_ty.ptr_to());
         bcx = datum.store_to(bcx, base);
 
-        let info = unsized_info_bcx(bcx, k, expr.id, unboxed_ty, base, bcx.fcx.param_substs,
-                                    |t| ty::mk_uniq(tcx, t));
+        let info = unsized_info_bcx(bcx, k, expr.id, unboxed_ty, base, bcx.fcx.param_substs);
         Store(bcx, info, get_len(bcx, scratch.val));
 
         DatumBlock::new(bcx, scratch.to_expr_datum())
@@ -888,10 +868,7 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                 }
             };
 
-            let vt =
-                tvec::vec_types(bcx,
-                                ty::sequence_element_type(bcx.tcx(),
-                                                          base_datum.ty));
+            let unit_ty = ty::sequence_element_type(bcx.tcx(), base_datum.ty);
 
             let (base, len) = base_datum.get_vec_base_and_len(bcx);
 
@@ -916,8 +893,8 @@ fn trans_index<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                                      len)
             });
             let elt = InBoundsGEP(bcx, base, &[ix_val]);
-            let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to());
-            Datum::new(elt, vt.unit_ty, LvalueExpr)
+            let elt = PointerCast(bcx, elt, type_of::type_of(ccx, unit_ty).ptr_to());
+            Datum::new(elt, unit_ty, LvalueExpr)
         }
     };
 
diff --git a/src/librustc_trans/trans/glue.rs b/src/librustc_trans/trans/glue.rs
index 1151b11d21f..b2de8435f64 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,24 +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::tvec;
 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,
@@ -178,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.
 
-    glue
+    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);
+
+    llfn
 }
 
 fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
@@ -386,51 +397,34 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
     let _icx = push_ctxt("make_drop_glue");
     match t.sty {
         ty::ty_uniq(content_ty) => {
-            match content_ty.sty {
-                ty::ty_vec(ty, None) => {
-                    tvec::make_drop_glue_unboxed(bcx, v0, ty, true)
-                }
-                ty::ty_str => {
-                    let unit_ty = ty::sequence_element_type(bcx.tcx(), content_ty);
-                    tvec::make_drop_glue_unboxed(bcx, v0, unit_ty, true)
-                }
-                ty::ty_trait(..) => {
-                    let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
-                    // Only drop the value when it is non-null
-                    let concrete_ptr = Load(bcx, lluniquevalue);
-                    with_cond(bcx, IsNotNull(bcx, concrete_ptr), |bcx| {
-                        let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
-                        let dtor = Load(bcx, dtor_ptr);
-                        Call(bcx,
-                             dtor,
-                             &[PointerCast(bcx, lluniquevalue, Type::i8p(bcx.ccx()))],
-                             None,
-                             DebugLoc::None);
-                        bcx
-                    })
-                }
-                ty::ty_struct(..) if !type_is_sized(bcx.tcx(), content_ty) => {
-                    let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
-                    let llbox = Load(bcx, llval);
-                    let not_null = IsNotNull(bcx, llbox);
-                    with_cond(bcx, not_null, |bcx| {
-                        let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
-                        let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
-                        let info = Load(bcx, info);
-                        let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
+            if !type_is_sized(bcx.tcx(), content_ty) {
+                let llval = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
+                let llbox = Load(bcx, llval);
+                let not_null = IsNotNull(bcx, llbox);
+                with_cond(bcx, not_null, |bcx| {
+                    let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
+                    let info = GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]);
+                    let info = Load(bcx, info);
+                    let (llsize, llalign) = size_and_align_of_dst(bcx, content_ty, info);
+
+                    // `Box<ZeroSizeType>` does not allocate.
+                    let needs_free = ICmp(bcx,
+                                          llvm::IntNE,
+                                          llsize,
+                                          C_uint(bcx.ccx(), 0u64),
+                                          DebugLoc::None);
+                    with_cond(bcx, needs_free, |bcx| {
                         trans_exchange_free_dyn(bcx, llbox, llsize, llalign, DebugLoc::None)
                     })
-                }
-                _ => {
-                    assert!(type_is_sized(bcx.tcx(), content_ty));
-                    let llval = v0;
-                    let llbox = Load(bcx, llval);
-                    let not_null = IsNotNull(bcx, llbox);
-                    with_cond(bcx, not_null, |bcx| {
-                        let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
-                        trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
-                    })
-                }
+                })
+            } else {
+                let llval = v0;
+                let llbox = Load(bcx, llval);
+                let not_null = IsNotNull(bcx, llbox);
+                with_cond(bcx, not_null, |bcx| {
+                    let bcx = drop_ty(bcx, llbox, content_ty, DebugLoc::None);
+                    trans_exchange_free_ty(bcx, llbox, content_ty, DebugLoc::None)
+                })
             }
         }
         ty::ty_struct(did, substs) | ty::ty_enum(did, substs) => {
@@ -462,34 +456,19 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, t: Ty<'tcx>)
                 }
             }
         }
-        ty::ty_closure(..) => {
-            iter_structural_ty(bcx,
-                               v0,
-                               t,
-                               |bb, vv, tt| drop_ty(bb, vv, tt, DebugLoc::None))
-        }
         ty::ty_trait(..) => {
-            // No need to do a null check here (as opposed to the Box<trait case
-            // above), because this happens for a trait field in an unsized
-            // struct. If anything is null, it is the whole struct and we won't
-            // get here.
-            let lluniquevalue = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
-            let dtor_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
-            let dtor = Load(bcx, dtor_ptr);
+            let data_ptr = GEPi(bcx, v0, &[0, abi::FAT_PTR_ADDR]);
+            let vtable_ptr = Load(bcx, GEPi(bcx, v0, &[0, abi::FAT_PTR_EXTRA]));
+            let dtor = Load(bcx, vtable_ptr);
             Call(bcx,
                  dtor,
-                 &[PointerCast(bcx, Load(bcx, lluniquevalue), Type::i8p(bcx.ccx()))],
+                 &[PointerCast(bcx, Load(bcx, data_ptr), Type::i8p(bcx.ccx()))],
                  None,
                  DebugLoc::None);
             bcx
-        },
-        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 bcx.fcx.type_needs_drop(t) && ty::type_is_structural(t) {
+            if bcx.fcx.type_needs_drop(t) {
                 iter_structural_ty(bcx,
                                    v0,
                                    t,
@@ -500,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 916492195c2..69ca9a5e81c 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 1552ac0bea0..9b17c4f8baa 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/meth.rs b/src/librustc_trans/trans/meth.rs
index ba3798d7d80..3f67c211f8c 100644
--- a/src/librustc_trans/trans/meth.rs
+++ b/src/librustc_trans/trans/meth.rs
@@ -680,11 +680,8 @@ pub fn trans_object_shim<'a, 'tcx>(
 ///
 /// The `trait_ref` encodes the erased self type. Hence if we are
 /// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
-/// `trait_ref` would map `T:Trait`, but `box_ty` would be
-/// `Foo<T>`. This `box_ty` is primarily used to encode the destructor.
-/// This will hopefully change now that DST is underway.
+/// `trait_ref` would map `T:Trait`.
 pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
-                            box_ty: Ty<'tcx>,
                             trait_ref: ty::PolyTraitRef<'tcx>,
                             param_substs: &'tcx subst::Substs<'tcx>)
                             -> ValueRef
@@ -692,13 +689,10 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let tcx = ccx.tcx();
     let _icx = push_ctxt("meth::get_vtable");
 
-    debug!("get_vtable(box_ty={}, trait_ref={})",
-           box_ty.repr(tcx),
-           trait_ref.repr(tcx));
+    debug!("get_vtable(trait_ref={})", trait_ref.repr(tcx));
 
     // Check the cache.
-    let cache_key = (box_ty, trait_ref.clone());
-    match ccx.vtables().borrow().get(&cache_key) {
+    match ccx.vtables().borrow().get(&trait_ref) {
         Some(&val) => { return val }
         None => { }
     }
@@ -755,7 +749,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 
     let components: Vec<_> = vec![
         // Generate a destructor for the vtable.
-        glue::get_drop_glue(ccx, box_ty),
+        glue::get_drop_glue(ccx, trait_ref.self_ty()),
         C_uint(ccx, size),
         C_uint(ccx, align)
     ].into_iter().chain(methods).collect();
@@ -763,7 +757,7 @@ pub fn get_vtable<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
     let vtable = consts::addr_of(ccx, C_struct(ccx, &components, false),
                                  "vtable", trait_ref.def_id().node);
 
-    ccx.vtables().borrow_mut().insert(cache_key, vtable);
+    ccx.vtables().borrow_mut().insert(trait_ref, vtable);
     vtable
 }
 
@@ -842,16 +836,15 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     debug!("trans_trait_cast: trait_ref={}",
            trait_ref.repr(bcx.tcx()));
 
-    let datum_ty = datum.ty;
-    let llbox_ty = type_of(bcx.ccx(), datum_ty);
+    let llty = type_of(bcx.ccx(), datum.ty);
 
     // Store the pointer into the first half of pair.
     let llboxdest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_ADDR]);
-    let llboxdest = PointerCast(bcx, llboxdest, llbox_ty.ptr_to());
+    let llboxdest = PointerCast(bcx, llboxdest, llty.ptr_to());
     bcx = datum.store_to(bcx, llboxdest);
 
     // Store the vtable into the second half of pair.
-    let vtable = get_vtable(bcx.ccx(), datum_ty, trait_ref, bcx.fcx.param_substs);
+    let vtable = get_vtable(bcx.ccx(), trait_ref, bcx.fcx.param_substs);
     let llvtabledest = GEPi(bcx, lldest, &[0, abi::FAT_PTR_EXTRA]);
     let llvtabledest = PointerCast(bcx, llvtabledest, val_ty(vtable).ptr_to());
     Store(bcx, vtable, llvtabledest);
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index 2fd79c1ddb4..6a35a1a55b6 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -24,8 +24,6 @@ use trans::datum::*;
 use trans::debuginfo::DebugLoc;
 use trans::expr::{Dest, Ignore, SaveIn};
 use trans::expr;
-use trans::glue;
-use trans::machine;
 use trans::machine::llsize_of_alloc;
 use trans::type_::Type;
 use trans::type_of;
@@ -35,79 +33,17 @@ use util::ppaux::ty_to_string;
 use syntax::ast;
 use syntax::parse::token::InternedString;
 
-fn get_len(bcx: Block, vptr: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("tvec::get_lenl");
-    Load(bcx, expr::get_len(bcx, vptr))
-}
-
-fn get_dataptr(bcx: Block, vptr: ValueRef) -> ValueRef {
-    let _icx = push_ctxt("tvec::get_dataptr");
-    Load(bcx, expr::get_dataptr(bcx, vptr))
-}
-
-pub fn make_drop_glue_unboxed<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                          vptr: ValueRef,
-                                          unit_ty: Ty<'tcx>,
-                                          should_deallocate: bool)
-                                          -> Block<'blk, 'tcx> {
-    let not_null = IsNotNull(bcx, vptr);
-    with_cond(bcx, not_null, |bcx| {
-        let ccx = bcx.ccx();
-        let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
-
-        let dataptr = get_dataptr(bcx, vptr);
-        let bcx = if bcx.fcx.type_needs_drop(unit_ty) {
-            let len = get_len(bcx, vptr);
-            iter_vec_raw(bcx,
-                         dataptr,
-                         unit_ty,
-                         len,
-                         |bb, vv, tt| glue::drop_ty(bb, vv, tt, DebugLoc::None))
-        } else {
-            bcx
-        };
-
-        if should_deallocate {
-            let llty = type_of::type_of(ccx, unit_ty);
-            let unit_size = llsize_of_alloc(ccx, llty);
-            if unit_size != 0 {
-                let len = get_len(bcx, vptr);
-                let not_empty = ICmp(bcx,
-                                     llvm::IntNE,
-                                     len,
-                                     C_uint(ccx, 0_u32),
-                                     DebugLoc::None);
-                with_cond(bcx, not_empty, |bcx| {
-                    let llalign = C_uint(ccx, machine::llalign_of_min(ccx, llty));
-                    let size = Mul(bcx, C_uint(ccx, unit_size), len, DebugLoc::None);
-                    glue::trans_exchange_free_dyn(bcx,
-                                                  dataptr,
-                                                  size,
-                                                  llalign,
-                                                  DebugLoc::None)
-                })
-            } else {
-                bcx
-            }
-        } else {
-            bcx
-        }
-    })
-}
-
 #[derive(Copy)]
-pub struct VecTypes<'tcx> {
-    pub unit_ty: Ty<'tcx>,
-    pub llunit_ty: Type,
-    pub llunit_alloc_size: u64
+struct VecTypes<'tcx> {
+    unit_ty: Ty<'tcx>,
+    llunit_ty: Type
 }
 
 impl<'tcx> VecTypes<'tcx> {
     pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String {
-        format!("VecTypes {{unit_ty={}, llunit_ty={}, llunit_alloc_size={}}}",
+        format!("VecTypes {{unit_ty={}, llunit_ty={}}}",
                 ty_to_string(ccx.tcx(), self.unit_ty),
-                ccx.tn().type_to_string(self.llunit_ty),
-                self.llunit_alloc_size)
+                ccx.tn().type_to_string(self.llunit_ty))
     }
 }
 
@@ -221,12 +157,12 @@ pub fn trans_lit_str<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                 vt: &VecTypes<'tcx>,
-                                 vstore_expr: &ast::Expr,
-                                 content_expr: &ast::Expr,
-                                 dest: Dest)
-                                 -> Block<'blk, 'tcx> {
+fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                             vt: &VecTypes<'tcx>,
+                             vstore_expr: &ast::Expr,
+                             content_expr: &ast::Expr,
+                             dest: Dest)
+                             -> Block<'blk, 'tcx> {
     let _icx = push_ctxt("tvec::write_content");
     let fcx = bcx.fcx;
     let mut bcx = bcx;
@@ -315,28 +251,21 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn vec_types_from_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                       vec_expr: &ast::Expr)
-                                       -> VecTypes<'tcx> {
+fn vec_types_from_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, vec_expr: &ast::Expr)
+                                   -> VecTypes<'tcx> {
     let vec_ty = node_id_type(bcx, vec_expr.id);
     vec_types(bcx, ty::sequence_element_type(bcx.tcx(), vec_ty))
 }
 
-pub fn vec_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                             unit_ty: Ty<'tcx>)
-                             -> VecTypes<'tcx> {
-    let ccx = bcx.ccx();
-    let llunit_ty = type_of::type_of(ccx, unit_ty);
-    let llunit_alloc_size = llsize_of_alloc(ccx, llunit_ty);
-
+fn vec_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, unit_ty: Ty<'tcx>)
+                         -> VecTypes<'tcx> {
     VecTypes {
         unit_ty: unit_ty,
-        llunit_ty: llunit_ty,
-        llunit_alloc_size: llunit_alloc_size
+        llunit_ty: type_of::type_of(bcx.ccx(), unit_ty)
     }
 }
 
-pub fn elements_required(bcx: Block, content_expr: &ast::Expr) -> uint {
+fn elements_required(bcx: Block, content_expr: &ast::Expr) -> uint {
     //! Figure out the number of elements we need to store this content
 
     match content_expr.node {
@@ -401,12 +330,12 @@ pub fn get_base_and_len<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
-                                     data_ptr: ValueRef,
-                                     vt: &VecTypes<'tcx>,
-                                     count: ValueRef,
-                                     f: F)
-                                     -> Block<'blk, 'tcx> where
+fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                data_ptr: ValueRef,
+                                vt: &VecTypes<'tcx>,
+                                count: ValueRef,
+                                f: F)
+                                -> Block<'blk, 'tcx> where
     F: FnOnce(Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
 {
     let _icx = push_ctxt("tvec::iter_vec_loop");
@@ -426,7 +355,7 @@ pub fn iter_vec_loop<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
     let bcx = loop_bcx;
 
-    let lleltptr = if vt.llunit_alloc_size == 0 {
+    let lleltptr = if llsize_of_alloc(bcx.ccx(), vt.llunit_ty) == 0 {
         data_ptr
     } else {
         InBoundsGEP(bcx, data_ptr, &[loop_counter])
@@ -454,7 +383,7 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
 
     let vt = vec_types(bcx, unit_ty);
 
-    if vt.llunit_alloc_size == 0 {
+    if llsize_of_alloc(bcx.ccx(), vt.llunit_ty) == 0 {
         // Special-case vectors with elements of size 0  so they don't go out of bounds (#9890)
         iter_vec_loop(bcx, data_ptr, &vt, len, f)
     } else {
@@ -471,7 +400,7 @@ pub fn iter_vec_raw<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
         let body_bcx = fcx.new_temp_block("iter_vec_loop_body");
         let next_bcx = fcx.new_temp_block("iter_vec_next");
         CondBr(header_bcx, not_yet_at_end, body_bcx.llbb, next_bcx.llbb, DebugLoc::None);
-        let body_bcx = f(body_bcx, data_ptr, vt.unit_ty);
+        let body_bcx = f(body_bcx, data_ptr, unit_ty);
         AddIncomingToPhi(data_ptr, InBoundsGEP(body_bcx, data_ptr,
                                                &[C_int(bcx.ccx(), 1)]),
                          body_bcx.llbb);
diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs
index d5ec18e641b..dcb57fd9cde 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 31bee612b78..de0978bc409 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 23726805767..97cc3ac7c48 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());
 
@@ -153,15 +144,6 @@ enum AstConvRequest {
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// 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
 // know later when parsing field defs.
diff --git a/src/test/run-pass/issue-21058.rs b/src/test/run-pass/issue-21058.rs
index 3cdd57aed5a..e53fe3c44a2 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::<str>()).name,
+        std::intrinsics::type_name::<str>(),
         // Trait
-        (*std::intrinsics::get_tydesc::<Copy>()).name,
+        std::intrinsics::type_name::<Copy>(),
         // Newtype
-        (*std::intrinsics::get_tydesc::<NT>()).name,
+        std::intrinsics::type_name::<NT>(),
         // DST
-        (*std::intrinsics::get_tydesc::<DST>()).name
+        std::intrinsics::type_name::<DST>()
     )}, ("[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 e3b148ac92d..2e7717fcfe1 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<T> {
     x: T
@@ -17,7 +17,7 @@ struct Foo<T> {
 
 pub fn main() {
     unsafe {
-        assert_eq!((*get_tydesc::<int>()).name, "isize");
-        assert_eq!((*get_tydesc::<Foo<uint>>()).name, "Foo<usize>");
+        assert_eq!(type_name::<int>(), "isize");
+        assert_eq!(type_name::<Foo<uint>>(), "Foo<usize>");
     }
 }