about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libextra/arena.rs29
-rw-r--r--src/libextra/dbg.rs34
-rw-r--r--src/librustc/driver/driver.rs3
-rw-r--r--src/librustc/front/intrinsic.rs148
-rw-r--r--src/librustc/front/intrinsic_inject.rs47
-rw-r--r--src/librustc/middle/lang_items.rs24
-rw-r--r--src/librustc/middle/trans/reflect.rs8
-rw-r--r--src/librustc/middle/ty.rs27
-rw-r--r--src/librustc/middle/typeck/check/mod.rs8
-rw-r--r--src/librustc/middle/typeck/collect.rs55
-rw-r--r--src/librustc/rustc.rc1
-rw-r--r--src/libstd/at_vec.rs13
-rw-r--r--src/libstd/cleanup.rs28
-rw-r--r--src/libstd/managed.rs2
-rw-r--r--src/libstd/reflect.rs6
-rw-r--r--src/libstd/repr.rs20
-rw-r--r--src/libstd/rt/global_heap.rs10
-rw-r--r--src/libstd/sys.rs12
-rw-r--r--src/libstd/unstable/exchange_alloc.rs10
-rw-r--r--src/libstd/unstable/intrinsics.rs129
-rw-r--r--src/libstd/vec.rs15
-rw-r--r--src/test/run-pass/extern-pub.rs6
-rw-r--r--src/test/run-pass/reflect-visit-data.rs20
23 files changed, 298 insertions, 357 deletions
diff --git a/src/libextra/arena.rs b/src/libextra/arena.rs
index db4cf564bab..a7d5660cd2e 100644
--- a/src/libextra/arena.rs
+++ b/src/libextra/arena.rs
@@ -43,20 +43,27 @@ use core::cast::{transmute, transmute_mut_region};
 use core::cast;
 use core::libc::size_t;
 use core::ptr;
-use core::sys::TypeDesc;
 use core::sys;
 use core::uint;
 use core::vec;
 use core::unstable::intrinsics;
 
+#[cfg(stage0)]
+use intrinsic::{get_tydesc, TyDesc};
+#[cfg(not(stage0))]
+use core::unstable::intrinsics::{get_tydesc, TyDesc};
+
 pub mod rustrt {
     use core::libc::size_t;
-    use core::sys::TypeDesc;
+    #[cfg(stage0)]
+    use intrinsic::{TyDesc};
+    #[cfg(not(stage0))]
+    use core::unstable::intrinsics::{TyDesc};
 
     pub extern {
         #[rust_stack]
         unsafe fn rust_call_tydesc_glue(root: *u8,
-                                        tydesc: *TypeDesc,
+                                        tydesc: *TyDesc,
                                         field: size_t);
     }
 }
@@ -136,7 +143,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
         let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
         let (size, align) = ((*tydesc).size, (*tydesc).align);
 
-        let after_tydesc = idx + sys::size_of::<*TypeDesc>();
+        let after_tydesc = idx + sys::size_of::<*TyDesc>();
 
         let start = round_up_to(after_tydesc, align);
 
@@ -148,7 +155,7 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
         }
 
         // Find where the next tydesc lives
-        idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>());
+        idx = round_up_to(start + size, sys::pref_align_of::<*TyDesc>());
     }
 }
 
@@ -157,12 +164,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
 // is necessary in order to properly do cleanup if a failure occurs
 // during an initializer.
 #[inline]
-unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
+unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
     let p_bits: uint = transmute(p);
     p_bits | (is_done as uint)
 }
 #[inline]
-unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
+unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
     (transmute(p & !1), p & 1 == 1)
 }
 
@@ -202,7 +209,7 @@ impl Arena {
     #[inline]
     fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
         unsafe {
-            let tydesc = sys::get_type_desc::<T>();
+            let tydesc = get_tydesc::<T>();
             let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
             let ptr: *mut T = transmute(ptr);
             intrinsics::move_val_init(&mut (*ptr), op());
@@ -230,13 +237,13 @@ impl Arena {
             let head = transmute_mut_region(&mut self.head);
 
             let tydesc_start = head.fill;
-            let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
+            let after_tydesc = head.fill + sys::size_of::<*TyDesc>();
             let start = round_up_to(after_tydesc, align);
             let end = start + n_bytes;
             if end > at_vec::capacity(head.data) {
                 return self.alloc_nonpod_grow(n_bytes, align);
             }
-            head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
+            head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>());
 
             //debug!("idx = %u, size = %u, align = %u, fill = %u",
             //       start, n_bytes, align, head.fill);
@@ -249,7 +256,7 @@ impl Arena {
     #[inline]
     fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
         unsafe {
-            let tydesc = sys::get_type_desc::<T>();
+            let tydesc = get_tydesc::<T>();
             let (ty_ptr, ptr) =
                 self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
             let ty_ptr: *mut uint = transmute(ty_ptr);
diff --git a/src/libextra/dbg.rs b/src/libextra/dbg.rs
index cbd7cb5e3c0..43c4aecdd27 100644
--- a/src/libextra/dbg.rs
+++ b/src/libextra/dbg.rs
@@ -13,56 +13,62 @@
 #[allow(missing_doc)];
 
 use core::cast::transmute;
-use core::sys;
+#[cfg(stage0)]
+use intrinsic::{get_tydesc};
+#[cfg(not(stage0))]
+use core::unstable::intrinsics::{get_tydesc};
 
 pub mod rustrt {
-    use core::sys;
+    #[cfg(stage0)]
+    use intrinsic::{TyDesc};
+    #[cfg(not(stage0))]
+    use core::unstable::intrinsics::{TyDesc};
 
     #[abi = "cdecl"]
     pub extern {
-        pub unsafe fn debug_tydesc(td: *sys::TypeDesc);
-        pub unsafe fn debug_opaque(td: *sys::TypeDesc, x: *());
-        pub unsafe fn debug_box(td: *sys::TypeDesc, x: *());
-        pub unsafe fn debug_tag(td: *sys::TypeDesc, x: *());
-        pub unsafe fn debug_fn(td: *sys::TypeDesc, x: *());
-        pub unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
+        pub unsafe fn debug_tydesc(td: *TyDesc);
+        pub unsafe fn debug_opaque(td: *TyDesc, x: *());
+        pub unsafe fn debug_box(td: *TyDesc, x: *());
+        pub unsafe fn debug_tag(td: *TyDesc, x: *());
+        pub unsafe fn debug_fn(td: *TyDesc, x: *());
+        pub unsafe fn debug_ptrcast(td: *TyDesc, x: *()) -> *();
         pub unsafe fn rust_dbg_breakpoint();
     }
 }
 
 pub fn debug_tydesc<T>() {
     unsafe {
-        rustrt::debug_tydesc(sys::get_type_desc::<T>());
+        rustrt::debug_tydesc(get_tydesc::<T>());
     }
 }
 
 pub fn debug_opaque<T>(x: T) {
     unsafe {
-        rustrt::debug_opaque(sys::get_type_desc::<T>(), transmute(&x));
+        rustrt::debug_opaque(get_tydesc::<T>(), transmute(&x));
     }
 }
 
 pub fn debug_box<T>(x: @T) {
     unsafe {
-        rustrt::debug_box(sys::get_type_desc::<T>(), transmute(&x));
+        rustrt::debug_box(get_tydesc::<T>(), transmute(&x));
     }
 }
 
 pub fn debug_tag<T>(x: T) {
     unsafe {
-        rustrt::debug_tag(sys::get_type_desc::<T>(), transmute(&x));
+        rustrt::debug_tag(get_tydesc::<T>(), transmute(&x));
     }
 }
 
 pub fn debug_fn<T>(x: T) {
     unsafe {
-        rustrt::debug_fn(sys::get_type_desc::<T>(), transmute(&x));
+        rustrt::debug_fn(get_tydesc::<T>(), transmute(&x));
     }
 }
 
 pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
     transmute(
-        rustrt::debug_ptrcast(sys::get_type_desc::<T>(), transmute(x)))
+        rustrt::debug_ptrcast(get_tydesc::<T>(), transmute(x)))
 }
 
 /// Triggers a debugger breakpoint
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 1a7041c0884..fbb273450df 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -206,9 +206,6 @@ pub fn compile_rest(sess: Session,
     let mut crate = crate_opt.unwrap();
 
     let (llcx, llmod, link_meta) = {
-    crate = time(time_passes, ~"intrinsic injection", ||
-                 front::intrinsic_inject::inject_intrinsic(sess, crate));
-
         crate = time(time_passes, ~"extra injection", ||
                      front::std_inject::maybe_inject_libstd_ref(sess, crate));
 
diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs
deleted file mode 100644
index f19e3706253..00000000000
--- a/src/librustc/front/intrinsic.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2012 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.
-
-// NB: this file is include_str!'ed into the compiler, re-parsed
-// and injected into each crate the compiler builds. Keep it small.
-
-pub mod intrinsic {
-    #[allow(missing_doc)];
-
-    pub use intrinsic::rusti::visit_tydesc;
-
-    // FIXME (#3727): remove this when the interface has settled and the
-    // version in sys is no longer present.
-    pub fn get_tydesc<T>() -> *TyDesc {
-        unsafe {
-            rusti::get_tydesc::<T>()
-        }
-    }
-
-    pub type GlueFn = extern "Rust" fn(**TyDesc, *i8);
-
-    // NB: this has to be kept in sync with the Rust ABI.
-    pub struct TyDesc {
-        size: uint,
-        align: uint,
-        take_glue: GlueFn,
-        drop_glue: GlueFn,
-        free_glue: GlueFn,
-        visit_glue: GlueFn,
-        shape: *i8,
-        shape_tables: *i8
-    }
-
-    pub enum Opaque { }
-
-    pub trait TyVisitor {
-        fn visit_bot(&self) -> bool;
-        fn visit_nil(&self) -> bool;
-        fn visit_bool(&self) -> bool;
-
-        fn visit_int(&self) -> bool;
-        fn visit_i8(&self) -> bool;
-        fn visit_i16(&self) -> bool;
-        fn visit_i32(&self) -> bool;
-        fn visit_i64(&self) -> bool;
-
-        fn visit_uint(&self) -> bool;
-        fn visit_u8(&self) -> bool;
-        fn visit_u16(&self) -> bool;
-        fn visit_u32(&self) -> bool;
-        fn visit_u64(&self) -> bool;
-
-        fn visit_float(&self) -> bool;
-        fn visit_f32(&self) -> bool;
-        fn visit_f64(&self) -> bool;
-
-        fn visit_char(&self) -> bool;
-        fn visit_str(&self) -> bool;
-
-        fn visit_estr_box(&self) -> bool;
-        fn visit_estr_uniq(&self) -> bool;
-        fn visit_estr_slice(&self) -> bool;
-        fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool;
-
-        fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
-
-        fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint,
-                            mtbl: uint, inner: *TyDesc) -> bool;
-
-        fn visit_enter_rec(&self, n_fields: uint,
-                           sz: uint, align: uint) -> bool;
-        fn visit_rec_field(&self, i: uint, name: &str,
-                           mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_leave_rec(&self, n_fields: uint,
-                           sz: uint, align: uint) -> bool;
-
-        fn visit_enter_class(&self, n_fields: uint,
-                             sz: uint, align: uint) -> bool;
-        fn visit_class_field(&self, i: uint, name: &str,
-                             mtbl: uint, inner: *TyDesc) -> bool;
-        fn visit_leave_class(&self, n_fields: uint,
-                             sz: uint, align: uint) -> bool;
-
-        fn visit_enter_tup(&self, n_fields: uint,
-                           sz: uint, align: uint) -> bool;
-        fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool;
-        fn visit_leave_tup(&self, n_fields: uint,
-                           sz: uint, align: uint) -> bool;
-
-        fn visit_enter_enum(&self, n_variants: uint,
-                            get_disr: extern unsafe fn(ptr: *Opaque) -> int,
-                            sz: uint, align: uint) -> bool;
-        fn visit_enter_enum_variant(&self, variant: uint,
-                                    disr_val: int,
-                                    n_fields: uint,
-                                    name: &str) -> bool;
-        fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool;
-        fn visit_leave_enum_variant(&self, variant: uint,
-                                    disr_val: int,
-                                    n_fields: uint,
-                                    name: &str) -> bool;
-        fn visit_leave_enum(&self, n_variants: uint,
-                            get_disr: extern unsafe fn(ptr: *Opaque) -> int,
-                            sz: uint, align: uint) -> bool;
-
-        fn visit_enter_fn(&self, purity: uint, proto: uint,
-                          n_inputs: uint, retstyle: uint) -> bool;
-        fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool;
-        fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool;
-        fn visit_leave_fn(&self, purity: uint, proto: uint,
-                          n_inputs: uint, retstyle: uint) -> bool;
-
-        fn visit_trait(&self) -> bool;
-        fn visit_var(&self) -> bool;
-        fn visit_var_integral(&self) -> bool;
-        fn visit_param(&self, i: uint) -> bool;
-        fn visit_self(&self) -> bool;
-        fn visit_type(&self) -> bool;
-        fn visit_opaque_box(&self) -> bool;
-        fn visit_constr(&self, inner: *TyDesc) -> bool;
-        fn visit_closure_ptr(&self, ck: uint) -> bool;
-    }
-
-    pub mod rusti {
-        use super::{TyDesc, TyVisitor};
-
-        #[abi = "rust-intrinsic"]
-        pub extern "rust-intrinsic" {
-            pub fn get_tydesc<T>() -> *TyDesc;
-            pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
-        }
-    }
-}
diff --git a/src/librustc/front/intrinsic_inject.rs b/src/librustc/front/intrinsic_inject.rs
deleted file mode 100644
index 0caadc8572e..00000000000
--- a/src/librustc/front/intrinsic_inject.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2012 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.
-
-use core::prelude::*;
-
-use core::vec;
-use driver::session::Session;
-use syntax::parse;
-use syntax::ast;
-use syntax::codemap::spanned;
-
-pub fn inject_intrinsic(sess: Session, crate: @ast::crate) -> @ast::crate {
-    let intrinsic_module = include_str!("intrinsic.rs").to_managed();
-
-    let item = parse::parse_item_from_source_str(@"<intrinsic>",
-                                                 intrinsic_module,
-                                                 /*bad*/copy sess.opts.cfg,
-                                                 ~[],
-                                                 sess.parse_sess);
-    let item =
-        match item {
-          Some(i) => i,
-          None => {
-            sess.fatal("no item found in intrinsic module");
-          }
-        };
-
-    let items = vec::append(~[item], crate.node.module.items);
-
-    @spanned {
-        node: ast::crate_ {
-            module: ast::_mod {
-                items: items,
-                .. /*bad*/copy crate.node.module
-            },
-            .. /*bad*/copy crate.node
-        },
-        .. /*bad*/copy *crate
-    }
-}
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 3a8d369469b..d73b019c1ea 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -76,16 +76,20 @@ pub enum LangItem {
     UnrecordBorrowFnLangItem,   // 36
 
     StartFnLangItem,            // 37
+
+    TyDescStructLangItem,       // 38
+    TyVisitorTraitLangItem,     // 39
+    OpaqueStructLangItem,       // 40
 }
 
 pub struct LanguageItems {
-    items: [Option<def_id>, ..38]
+    items: [Option<def_id>, ..41]
 }
 
 impl LanguageItems {
     pub fn new() -> LanguageItems {
         LanguageItems {
-            items: [ None, ..38 ]
+            items: [ None, ..41 ]
         }
     }
 
@@ -138,6 +142,10 @@ impl LanguageItems {
 
             37 => "start",
 
+            38 => "ty_desc",
+            39 => "ty_visitor",
+            40 => "opaque",
+
             _ => "???"
         }
     }
@@ -262,6 +270,15 @@ impl LanguageItems {
     pub fn start_fn(&const self) -> def_id {
         self.items[StartFnLangItem as uint].get()
     }
+    pub fn ty_desc(&const self) -> def_id {
+        self.items[TyDescStructLangItem as uint].get()
+    }
+    pub fn ty_visitor(&const self) -> def_id {
+        self.items[TyVisitorTraitLangItem as uint].get()
+    }
+    pub fn opaque(&const self) -> def_id {
+        self.items[OpaqueStructLangItem as uint].get()
+    }
 }
 
 fn LanguageItemCollector(crate: @crate,
@@ -313,6 +330,9 @@ fn LanguageItemCollector(crate: @crate,
     item_refs.insert(@"record_borrow", RecordBorrowFnLangItem as uint);
     item_refs.insert(@"unrecord_borrow", UnrecordBorrowFnLangItem as uint);
     item_refs.insert(@"start", StartFnLangItem as uint);
+    item_refs.insert(@"ty_desc", TyDescStructLangItem as uint);
+    item_refs.insert(@"ty_visitor", TyVisitorTraitLangItem as uint);
+    item_refs.insert(@"opaque", OpaqueStructLangItem as uint);
 
     LanguageItemCollector {
         crate: crate,
diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs
index cb68a2af92b..9e5510fc605 100644
--- a/src/librustc/middle/trans/reflect.rs
+++ b/src/librustc/middle/trans/reflect.rs
@@ -274,9 +274,7 @@ impl Reflector {
             let repr = adt::represent_type(bcx.ccx(), t);
             let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
             let llptrty = type_of(ccx, t).ptr_to();
-            let (_, opaquety) =
-                ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of("Opaque"))
-                .expect("Failed to resolve intrinsic::Opaque");
+            let opaquety = ty::get_opaque_ty(ccx.tcx);
             let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm });
 
             let make_get_disr = || {
@@ -373,10 +371,8 @@ pub fn emit_calls_to_trait_visit_ty(bcx: block,
                                     visitor_val: ValueRef,
                                     visitor_trait_id: def_id)
                                  -> block {
-    use syntax::parse::token::special_idents::tydesc;
     let final = sub_block(bcx, "final");
-    assert!(bcx.ccx().tcx.intrinsic_defs.contains_key(&tydesc));
-    let (_, tydesc_ty) = bcx.ccx().tcx.intrinsic_defs.get_copy(&tydesc);
+    let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx);
     let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
     let mut r = Reflector {
         visitor_val: visitor_val,
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index a367cf4c430..f12ecebc6d5 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -44,7 +44,6 @@ use syntax::attr;
 use syntax::codemap::span;
 use syntax::codemap;
 use syntax::parse::token;
-use syntax::parse::token::special_idents;
 use syntax::{ast, ast_map};
 use syntax::opt_vec::OptVec;
 use syntax::opt_vec;
@@ -276,8 +275,7 @@ struct ctxt_ {
     trait_defs: @mut HashMap<def_id, @TraitDef>,
 
     items: ast_map::map,
-    intrinsic_defs: @mut HashMap<ast::ident, (ast::def_id, t)>,
-    intrinsic_traits: @mut HashMap<ast::ident, @TraitRef>,
+    intrinsic_defs: @mut HashMap<ast::def_id, t>,
     freevars: freevars::freevar_map,
     tcache: type_cache,
     rcache: creader_cache,
@@ -953,7 +951,6 @@ pub fn mk_ctxt(s: session::Session,
         node_type_substs: @mut HashMap::new(),
         trait_refs: @mut HashMap::new(),
         trait_defs: @mut HashMap::new(),
-        intrinsic_traits: @mut HashMap::new(),
         items: amap,
         intrinsic_defs: @mut HashMap::new(),
         freevars: freevars,
@@ -4449,10 +4446,26 @@ pub fn get_impl_id(tcx: ctxt, trait_id: def_id, self_ty: t) -> def_id {
     }
 }
 
+pub fn get_tydesc_ty(tcx: ctxt) -> t {
+    let tydesc_lang_item = tcx.lang_items.ty_desc();
+    tcx.intrinsic_defs.find_copy(&tydesc_lang_item)
+        .expect("Failed to resolve TyDesc")
+}
+
+pub fn get_opaque_ty(tcx: ctxt) -> t {
+    let tydesc_lang_item = tcx.lang_items.opaque();
+    tcx.intrinsic_defs.find_copy(&tydesc_lang_item)
+        .expect("Failed to resolve Opaque")
+}
+
 pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
-    let ty_visitor_name = special_idents::ty_visitor;
-    assert!(tcx.intrinsic_traits.contains_key(&ty_visitor_name));
-    let trait_ref = tcx.intrinsic_traits.get_copy(&ty_visitor_name);
+    let substs = substs {
+        self_r: None,
+        self_ty: None,
+        tps: ~[]
+    };
+    let trait_lang_item = tcx.lang_items.ty_visitor();
+    let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs };
     (trait_ref,
      mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs, BoxTraitStore, ast::m_imm))
 }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 4c074ce197e..821daee8bfb 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -3506,9 +3506,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
             }
 
             "get_tydesc" => {
-              let tydesc_name = special_idents::tydesc;
-              assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
-              let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name);
+              let tydesc_ty = ty::get_tydesc_ty(ccx.tcx);
               let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
                   ty: tydesc_ty,
                   mutbl: ast::m_imm
@@ -3516,9 +3514,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
               (1u, ~[], td_ptr)
             }
             "visit_tydesc" => {
-              let tydesc_name = special_idents::tydesc;
-              assert!(tcx.intrinsic_defs.contains_key(&tydesc_name));
-              let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name);
+              let tydesc_ty = ty::get_tydesc_ty(ccx.tcx);
               let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
               let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
                   ty: tydesc_ty,
diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs
index 7f820d11ac6..756bb4d1bb9 100644
--- a/src/librustc/middle/typeck/collect.rs
+++ b/src/librustc/middle/typeck/collect.rs
@@ -62,55 +62,16 @@ use syntax::opt_vec::OptVec;
 use syntax::opt_vec;
 
 pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
-
-    // FIXME (#2592): hooking into the "intrinsic" root module is crude.
-    // There ought to be a better approach. Attributes?
-
-    for crate.node.module.items.iter().advance |crate_item| {
-        if crate_item.ident
-            == ::syntax::parse::token::special_idents::intrinsic {
-
-            match crate_item.node {
-              ast::item_mod(ref m) => {
-                for m.items.iter().advance |intrinsic_item| {
-                    let def_id = ast::def_id { crate: ast::local_crate,
-                                               node: intrinsic_item.id };
-                    let substs = substs {
-                        self_r: None,
-                        self_ty: None,
-                        tps: ~[]
-                    };
-
-                    match intrinsic_item.node {
-                      ast::item_trait(*) => {
-                          let tref = @ty::TraitRef {def_id: def_id,
-                                                    substs: substs};
-                          ccx.tcx.intrinsic_traits.insert
-                              (intrinsic_item.ident, tref);
-                      }
-
-                      ast::item_enum(*) => {
-                        let ty = ty::mk_enum(ccx.tcx, def_id, substs);
-                        ccx.tcx.intrinsic_defs.insert
-                            (intrinsic_item.ident, (def_id, ty));
-                      }
-
-                      ast::item_struct(*) => {
-                        let ty = ty::mk_struct(ccx.tcx, def_id, substs);
-                        ccx.tcx.intrinsic_defs.insert
-                            (intrinsic_item.ident, (def_id, ty));
-                      }
-
-                      _ => {}
-                    }
-                }
-              }
-              _ => { }
-            }
-            break;
-        }
+    fn collect_intrinsic_type(ccx: @mut CrateCtxt,
+                              lang_item: ast::def_id) {
+        let ty::ty_param_bounds_and_ty { ty: ty, _ } =
+            ccx.get_item_ty(lang_item);
+        ccx.tcx.intrinsic_defs.insert(lang_item, ty);
     }
 
+    collect_intrinsic_type(ccx, ccx.tcx.lang_items.ty_desc());
+    collect_intrinsic_type(ccx, ccx.tcx.lang_items.opaque());
+
     visit::visit_crate(
         crate, ((),
         visit::mk_simple_visitor(@visit::SimpleVisitor {
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index d59a308beb5..20705b3d797 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -86,7 +86,6 @@ pub mod front {
     pub mod config;
     pub mod test;
     pub mod std_inject;
-    pub mod intrinsic_inject;
 }
 
 pub mod back {
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 2b846c923c4..52115692dbc 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -26,13 +26,16 @@ use vec::ImmutableVector;
 
 pub mod rustrt {
     use libc;
-    use sys;
     use vec;
+    #[cfg(stage0)]
+    use intrinsic::{TyDesc};
+    #[cfg(not(stage0))]
+    use unstable::intrinsics::{TyDesc};
 
     #[abi = "cdecl"]
     #[link_name = "rustrt"]
     pub extern {
-        pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
+        pub unsafe fn vec_reserve_shared_actual(t: *TyDesc,
                                                 v: **vec::raw::VecRepr,
                                                 n: libc::size_t);
     }
@@ -198,6 +201,10 @@ pub mod raw {
     use uint;
     use unstable::intrinsics::{move_val_init};
     use vec;
+    #[cfg(stage0)]
+    use intrinsic::{get_tydesc};
+    #[cfg(not(stage0))]
+    use unstable::intrinsics::{get_tydesc};
 
     pub type VecRepr = vec::raw::VecRepr;
     pub type SliceRepr = vec::raw::SliceRepr;
@@ -259,7 +266,7 @@ pub mod raw {
         // Only make the (slow) call into the runtime if we have to
         if capacity(*v) < n {
             let ptr: **VecRepr = transmute(v);
-            rustrt::vec_reserve_shared_actual(sys::get_type_desc::<T>(),
+            rustrt::vec_reserve_shared_actual(get_tydesc::<T>(),
                                               ptr, n as libc::size_t);
         }
     }
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
index d1460b7a3c9..28aab9adad2 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -10,24 +10,18 @@
 
 #[doc(hidden)];
 
-use libc::{c_char, c_void, intptr_t, uintptr_t};
-use ptr::mut_null;
+use libc::{c_char, intptr_t, uintptr_t};
+use ptr::{mut_null, to_unsafe_ptr};
 use repr::BoxRepr;
-use sys::TypeDesc;
 use cast::transmute;
 #[cfg(not(test))] use unstable::lang::clear_task_borrow_list;
 
-#[cfg(not(test))] use ptr::to_unsafe_ptr;
-
 /**
  * Runtime structures
  *
  * NB: These must match the representation in the C++ runtime.
  */
 
-type DropGlue<'self> = &'self fn(**TypeDesc, *c_void);
-type FreeGlue<'self> = &'self fn(**TypeDesc, *c_void);
-
 type TaskID = uintptr_t;
 
 struct StackSegment { priv opaque: () }
@@ -164,6 +158,20 @@ fn debug_mem() -> bool {
     false
 }
 
+#[cfg(stage0)]
+unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) {
+    use sys::TypeDesc;
+
+    let tydesc: *TypeDesc = transmute(tydesc);
+    let drop_glue: extern "Rust" fn(**TypeDesc, *i8) = transmute((*tydesc).drop_glue);
+    drop_glue(to_unsafe_ptr(&tydesc), data);
+}
+
+#[cfg(not(stage0))]
+unsafe fn call_drop_glue(tydesc: *::std::unstable::intrinsics::TyDesc, data: *i8) {
+    ((*tydesc).drop_glue)(to_unsafe_ptr(&tydesc), data);
+}
+
 /// Destroys all managed memory (i.e. @ boxes) held by the current task.
 #[cfg(not(test))]
 #[lang="annihilate"]
@@ -205,9 +213,7 @@ pub unsafe fn annihilate() {
     // callback, as the original value may have been freed.
     for each_live_alloc(false) |box, uniq| {
         if !uniq {
-            let tydesc: *TypeDesc = transmute(copy (*box).header.type_desc);
-            let drop_glue: DropGlue = transmute(((*tydesc).drop_glue, 0));
-            drop_glue(to_unsafe_ptr(&tydesc), transmute(&(*box).data));
+            call_drop_glue((*box).header.type_desc, transmute(&(*box).data));
         }
     }
 
diff --git a/src/libstd/managed.rs b/src/libstd/managed.rs
index d514612b5af..b71b3b503c2 100644
--- a/src/libstd/managed.rs
+++ b/src/libstd/managed.rs
@@ -15,7 +15,7 @@ use ptr::to_unsafe_ptr;
 #[cfg(not(test))] use cmp::{Eq, Ord};
 
 pub mod raw {
-    use intrinsic::TyDesc;
+    use std::unstable::intrinsics::TyDesc;
 
     pub static RC_EXCHANGE_UNIQUE : uint = (-1) as uint;
     pub static RC_MANAGED_UNIQUE : uint = (-2) as uint;
diff --git a/src/libstd/reflect.rs b/src/libstd/reflect.rs
index d276abf0c8b..16ab4771d0d 100644
--- a/src/libstd/reflect.rs
+++ b/src/libstd/reflect.rs
@@ -16,8 +16,10 @@ Runtime type reflection
 
 #[allow(missing_doc)];
 
-use intrinsic::{TyDesc, TyVisitor};
-use intrinsic::Opaque;
+#[cfg(stage0)]
+use intrinsic::{Opaque, TyDesc, TyVisitor};
+#[cfg(not(stage0))]
+use unstable::intrinsics::{Opaque, TyDesc, TyVisitor};
 use libc::c_void;
 use sys;
 use vec;
diff --git a/src/libstd/repr.rs b/src/libstd/repr.rs
index ab3f83d34d5..f39b5a00ed0 100644
--- a/src/libstd/repr.rs
+++ b/src/libstd/repr.rs
@@ -19,9 +19,6 @@ More runtime type reflection
 use cast::transmute;
 use char;
 use container::Container;
-use intrinsic;
-use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
-use intrinsic::Opaque;
 use io::{Writer, WriterUtil};
 use iterator::IteratorUtil;
 use libc::c_void;
@@ -34,6 +31,10 @@ use to_str::ToStr;
 use vec::raw::{VecRepr, SliceRepr};
 use vec;
 use vec::{OwnedVector, UnboxedVecRepr};
+#[cfg(stage0)]
+use intrinsic::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
+#[cfg(not(stage0))]
+use unstable::intrinsics::{Opaque, TyDesc, TyVisitor, get_tydesc, visit_tydesc};
 
 #[cfg(test)] use io;
 
@@ -564,6 +565,7 @@ impl TyVisitor for ReprVisitor {
     fn visit_self(&self) -> bool { true }
     fn visit_type(&self) -> bool { true }
 
+    #[cfg(not(stage0))]
     fn visit_opaque_box(&self) -> bool {
         self.writer.write_char('@');
         do self.get::<&managed::raw::BoxRepr> |b| {
@@ -571,6 +573,16 @@ impl TyVisitor for ReprVisitor {
             self.visit_ptr_inner(p, b.header.type_desc);
         }
     }
+    #[cfg(stage0)]
+    fn visit_opaque_box(&self) -> bool {
+        self.writer.write_char('@');
+        do self.get::<&managed::raw::BoxRepr> |b| {
+            let p = ptr::to_unsafe_ptr(&b.data) as *c_void;
+            unsafe {
+                self.visit_ptr_inner(p, transmute(b.header.type_desc));
+            }
+        }
+    }
 
     // Type no longer exists, vestigial function.
     fn visit_constr(&self, _inner: *TyDesc) -> bool { fail!(); }
@@ -581,7 +593,7 @@ impl TyVisitor for ReprVisitor {
 pub fn write_repr<T>(writer: @Writer, object: &T) {
     unsafe {
         let ptr = ptr::to_unsafe_ptr(object) as *c_void;
-        let tydesc = intrinsic::get_tydesc::<T>();
+        let tydesc = get_tydesc::<T>();
         let u = ReprVisitor(ptr, writer);
         let v = reflect::MovePtrAdaptor(u);
         visit_tydesc(tydesc, @v as @TyVisitor)
diff --git a/src/libstd/rt/global_heap.rs b/src/libstd/rt/global_heap.rs
index ce7ff87b445..1e9f9aab834 100644
--- a/src/libstd/rt/global_heap.rs
+++ b/src/libstd/rt/global_heap.rs
@@ -8,26 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use sys::{TypeDesc, size_of};
+use sys::{size_of};
 use libc::{c_void, size_t, uintptr_t};
 use c_malloc = libc::malloc;
 use c_free = libc::free;
 use managed::raw::{BoxHeaderRepr, BoxRepr};
 use cast::transmute;
-use unstable::intrinsics::{atomic_xadd,atomic_xsub};
+use unstable::intrinsics::{atomic_xadd,atomic_xsub,TyDesc};
 use ptr::null;
-use intrinsic::TyDesc;
 
-pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void {
+pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void {
     assert!(td.is_not_null());
 
     let total_size = get_box_size(size, (*td).align);
     let p = c_malloc(total_size as size_t);
     assert!(p.is_not_null());
 
-    // FIXME #3475: Converting between our two different tydesc types
-    let td: *TyDesc = transmute(td);
-
     let box: &mut BoxRepr = transmute(p);
     box.header.ref_count = -1; // Exchange values not ref counted
     box.header.type_desc = td;
diff --git a/src/libstd/sys.rs b/src/libstd/sys.rs
index 79ea60cc224..7f80375c2f6 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -17,14 +17,13 @@ use cast;
 use gc;
 use io;
 use libc;
-use libc::{c_void, c_char, size_t};
+use libc::{c_char, size_t};
 use repr;
 use str;
 use unstable::intrinsics;
 
-pub type FreeGlue<'self> = &'self fn(*TypeDesc, *c_void);
-
 // Corresponds to runtime type_desc type
+#[cfg(stage0)]
 pub struct TypeDesc {
     size: uint,
     align: uint,
@@ -58,16 +57,11 @@ pub mod rustrt {
  * performing dark magick.
  */
 #[inline]
+#[cfg(stage0)]
 pub fn get_type_desc<T>() -> *TypeDesc {
     unsafe { intrinsics::get_tydesc::<T>() as *TypeDesc }
 }
 
-/// Returns a pointer to a type descriptor.
-#[inline]
-pub fn get_type_desc_val<T>(_val: &T) -> *TypeDesc {
-    get_type_desc::<T>()
-}
-
 /// Returns the size of a type
 #[inline]
 pub fn size_of<T>() -> uint {
diff --git a/src/libstd/unstable/exchange_alloc.rs b/src/libstd/unstable/exchange_alloc.rs
index 3b35c2fb804..5c47901df48 100644
--- a/src/libstd/unstable/exchange_alloc.rs
+++ b/src/libstd/unstable/exchange_alloc.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use sys::{TypeDesc, size_of};
+use sys::size_of;
 use libc::{c_void, size_t};
 use c_malloc = libc::malloc;
 use c_free = libc::free;
@@ -16,18 +16,18 @@ use managed::raw::{BoxHeaderRepr, BoxRepr};
 use cast::transmute;
 use unstable::intrinsics::{atomic_xadd,atomic_xsub};
 use ptr::null;
+#[cfg(stage0)]
 use intrinsic::TyDesc;
+#[cfg(not(stage0))]
+use unstable::intrinsics::TyDesc;
 
-pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void {
+pub unsafe fn malloc(td: *TyDesc, size: uint) -> *c_void {
     assert!(td.is_not_null());
 
     let total_size = get_box_size(size, (*td).align);
     let p = c_malloc(total_size as size_t);
     assert!(p.is_not_null());
 
-    // FIXME #3475: Converting between our two different tydesc types
-    let td: *TyDesc = transmute(td);
-
     let box: &mut BoxRepr = transmute(p);
     box.header.ref_count = -1; // Exchange values not ref counted
     box.header.type_desc = td;
diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs
index 08fc90fa908..a51ba05710b 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -32,6 +32,128 @@ A quick refresher on memory ordering:
 
 */
 
+// This is needed to prevent duplicate lang item definitions.
+#[cfg(test)]
+pub use realstd::unstable::intrinsics::{TyDesc, Opaque, TyVisitor};
+
+pub type GlueFn = extern "Rust" fn(**TyDesc, *i8);
+
+// NB: this has to be kept in sync with the Rust ABI.
+#[lang="ty_desc"]
+#[cfg(not(test))]
+pub struct TyDesc {
+    size: uint,
+    align: uint,
+    take_glue: GlueFn,
+    drop_glue: GlueFn,
+    free_glue: GlueFn,
+    visit_glue: GlueFn,
+    shape: *i8,
+    shape_tables: *i8
+}
+
+#[lang="opaque"]
+#[cfg(not(test))]
+pub enum Opaque { }
+
+#[lang="ty_visitor"]
+#[cfg(not(test))]
+pub trait TyVisitor {
+    fn visit_bot(&self) -> bool;
+    fn visit_nil(&self) -> bool;
+    fn visit_bool(&self) -> bool;
+
+    fn visit_int(&self) -> bool;
+    fn visit_i8(&self) -> bool;
+    fn visit_i16(&self) -> bool;
+    fn visit_i32(&self) -> bool;
+    fn visit_i64(&self) -> bool;
+
+    fn visit_uint(&self) -> bool;
+    fn visit_u8(&self) -> bool;
+    fn visit_u16(&self) -> bool;
+    fn visit_u32(&self) -> bool;
+    fn visit_u64(&self) -> bool;
+
+    fn visit_float(&self) -> bool;
+    fn visit_f32(&self) -> bool;
+    fn visit_f64(&self) -> bool;
+
+    fn visit_char(&self) -> bool;
+    fn visit_str(&self) -> bool;
+
+    fn visit_estr_box(&self) -> bool;
+    fn visit_estr_uniq(&self) -> bool;
+    fn visit_estr_slice(&self) -> bool;
+    fn visit_estr_fixed(&self, n: uint, sz: uint, align: uint) -> bool;
+
+    fn visit_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_ptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_rptr(&self, mtbl: uint, inner: *TyDesc) -> bool;
+
+    fn visit_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_unboxed_vec(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_evec_box(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_evec_uniq(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_evec_slice(&self, mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_evec_fixed(&self, n: uint, sz: uint, align: uint,
+                        mtbl: uint, inner: *TyDesc) -> bool;
+
+    fn visit_enter_rec(&self, n_fields: uint,
+                       sz: uint, align: uint) -> bool;
+    fn visit_rec_field(&self, i: uint, name: &str,
+                       mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_leave_rec(&self, n_fields: uint,
+                       sz: uint, align: uint) -> bool;
+
+    fn visit_enter_class(&self, n_fields: uint,
+                         sz: uint, align: uint) -> bool;
+    fn visit_class_field(&self, i: uint, name: &str,
+                         mtbl: uint, inner: *TyDesc) -> bool;
+    fn visit_leave_class(&self, n_fields: uint,
+                         sz: uint, align: uint) -> bool;
+
+    fn visit_enter_tup(&self, n_fields: uint,
+                       sz: uint, align: uint) -> bool;
+    fn visit_tup_field(&self, i: uint, inner: *TyDesc) -> bool;
+    fn visit_leave_tup(&self, n_fields: uint,
+                       sz: uint, align: uint) -> bool;
+
+    fn visit_enter_enum(&self, n_variants: uint,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        sz: uint, align: uint) -> bool;
+    fn visit_enter_enum_variant(&self, variant: uint,
+                                disr_val: int,
+                                n_fields: uint,
+                                name: &str) -> bool;
+    fn visit_enum_variant_field(&self, i: uint, offset: uint, inner: *TyDesc) -> bool;
+    fn visit_leave_enum_variant(&self, variant: uint,
+                                disr_val: int,
+                                n_fields: uint,
+                                name: &str) -> bool;
+    fn visit_leave_enum(&self, n_variants: uint,
+                        get_disr: extern unsafe fn(ptr: *Opaque) -> int,
+                        sz: uint, align: uint) -> bool;
+
+    fn visit_enter_fn(&self, purity: uint, proto: uint,
+                      n_inputs: uint, retstyle: uint) -> bool;
+    fn visit_fn_input(&self, i: uint, mode: uint, inner: *TyDesc) -> bool;
+    fn visit_fn_output(&self, retstyle: uint, inner: *TyDesc) -> bool;
+    fn visit_leave_fn(&self, purity: uint, proto: uint,
+                      n_inputs: uint, retstyle: uint) -> bool;
+
+    fn visit_trait(&self) -> bool;
+    fn visit_var(&self) -> bool;
+    fn visit_var_integral(&self) -> bool;
+    fn visit_param(&self, i: uint) -> bool;
+    fn visit_self(&self) -> bool;
+    fn visit_type(&self) -> bool;
+    fn visit_opaque_box(&self) -> bool;
+    fn visit_constr(&self, inner: *TyDesc) -> bool;
+    fn visit_closure_ptr(&self, ck: uint) -> bool;
+}
+
 #[abi = "rust-intrinsic"]
 pub extern "rust-intrinsic" {
 
@@ -210,7 +332,7 @@ pub extern "rust-intrinsic" {
 
     /// Get a static pointer to a type descriptor.
     #[cfg(not(stage0))]
-    pub fn get_tydesc<T>() -> *::intrinsic::TyDesc;
+    pub fn get_tydesc<T>() -> *TyDesc;
     #[cfg(stage0)]
     pub fn get_tydesc<T>() -> *();
 
@@ -234,9 +356,8 @@ pub extern "rust-intrinsic" {
     /// Returns `true` if a type requires drop glue.
     pub fn needs_drop<T>() -> bool;
 
-    // XXX: intrinsic uses legacy modes and has reference to TyDesc
-    // and TyVisitor which are in librustc
-    //fn visit_tydesc(++td: *TyDesc, &&tv: TyVisitor) -> ();
+    #[cfg(not(stage0))]
+    pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
 
     pub fn frame_address(f: &once fn(*u8));
 
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 17eb7e8e82b..fdf33df3a8a 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -31,6 +31,10 @@ use sys;
 use sys::size_of;
 use uint;
 use unstable::intrinsics;
+#[cfg(stage0)]
+use intrinsic::{get_tydesc};
+#[cfg(not(stage0))]
+use unstable::intrinsics::{get_tydesc};
 use vec;
 use util;
 
@@ -38,19 +42,22 @@ use util;
 
 pub mod rustrt {
     use libc;
-    use sys;
     use vec::raw;
+    #[cfg(stage0)]
+    use intrinsic::{TyDesc};
+    #[cfg(not(stage0))]
+    use unstable::intrinsics::{TyDesc};
 
     #[abi = "cdecl"]
     pub extern {
         // These names are terrible. reserve_shared applies
         // to ~[] and reserve_shared_actual applies to @[].
         #[fast_ffi]
-        unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
+        unsafe fn vec_reserve_shared(t: *TyDesc,
                                      v: **raw::VecRepr,
                                      n: libc::size_t);
         #[fast_ffi]
-        unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
+        unsafe fn vec_reserve_shared_actual(t: *TyDesc,
                                             v: **raw::VecRepr,
                                             n: libc::size_t);
     }
@@ -79,7 +86,7 @@ pub fn reserve<T>(v: &mut ~[T], n: uint) {
     if capacity(v) < n {
         unsafe {
             let ptr: **raw::VecRepr = cast::transmute(v);
-            let td = sys::get_type_desc::<T>();
+            let td = get_tydesc::<T>();
             if ((**ptr).box_header.ref_count ==
                 managed::raw::RC_MANAGED_UNIQUE) {
                 rustrt::vec_reserve_shared_actual(td, ptr, n as libc::size_t);
diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs
index 29b0457fc05..2d6cc2c78de 100644
--- a/src/test/run-pass/extern-pub.rs
+++ b/src/test/run-pass/extern-pub.rs
@@ -1,11 +1,7 @@
 use std::libc;
-use std::sys;
-use std::vec;
 
 extern {
-    pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
-                                            v: **vec::raw::VecRepr,
-                                            n: libc::size_t);
+    pub unsafe fn free(p: *libc::c_void);
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs
index a8571ab7325..176e49e0ea1 100644
--- a/src/test/run-pass/reflect-visit-data.rs
+++ b/src/test/run-pass/reflect-visit-data.rs
@@ -10,15 +10,14 @@
 
 // xfail-fast
 
-use std::bool;
 use std::int;
 use std::libc::c_void;
 use std::ptr;
 use std::sys;
 use std::vec::UnboxedVecRepr;
-use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
+use std::unstable::intrinsics::{TyDesc, get_tydesc, visit_tydesc, TyVisitor, Opaque};
 
-#[doc = "High-level interfaces to `intrinsic::visit_ty` reflection system."]
+#[doc = "High-level interfaces to `std::unstable::intrinsics::visit_ty` reflection system."]
 
 /// Trait for visitor that wishes to reflect on data.
 trait movable_ptr {
@@ -637,7 +636,9 @@ impl TyVisitor for my_visitor {
 }
 
 fn get_tydesc_for<T>(_t: T) -> *TyDesc {
-    get_tydesc::<T>()
+    unsafe {
+        get_tydesc::<T>()
+    }
 }
 
 struct Triple { x: int, y: int, z: int }
@@ -651,8 +652,8 @@ pub fn main() {
                                        vals: ~[]});
         let v = ptr_visit_adaptor(Inner {inner: u});
         let td = get_tydesc_for(r);
-        unsafe { error!("tydesc sz: %u, align: %u",
-                        (*td).size, (*td).align); }
+        error!("tydesc sz: %u, align: %u",
+               (*td).size, (*td).align);
         let v = @v as @TyVisitor;
         visit_tydesc(td, v);
 
@@ -661,8 +662,7 @@ pub fn main() {
             println(fmt!("val: %s", *s));
         }
         error!("%?", u.vals.clone());
-        assert!(u.vals == ~[
-            ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"
-        ]);
+        assert_eq!(u.vals.clone(),
+                   ~[ ~"1", ~"2", ~"3", ~"true", ~"false", ~"5", ~"4", ~"3", ~"12"]);
     }
- }
+}