about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-25 04:38:06 -0700
committerbors <bors@rust-lang.org>2013-06-25 04:38:06 -0700
commit7aee5da08db11dc597907bf228c2e716a408fdab (patch)
tree7217207f8ec916aca96034f94d64a15746e22f79 /src/libstd
parentb11346bb5d2659313eb96f3108137f01239785c9 (diff)
parentf8ae3cdcaacb29c7b56e546a9ddab1396b615f8f (diff)
downloadrust-7aee5da08db11dc597907bf228c2e716a408fdab.tar.gz
rust-7aee5da08db11dc597907bf228c2e716a408fdab.zip
auto merge of #7254 : Blei/rust/intrinsic-overhaul, r=cmr
This sets the `get_tydesc()` return type correctly and removes the intrinsic module. See #3730, #3475.

Update: this now also removes the unused shape fields in tydescs.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs13
-rw-r--r--src/libstd/cleanup.rs30
-rw-r--r--src/libstd/gc.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.rs31
-rw-r--r--src/libstd/unstable/exchange_alloc.rs10
-rw-r--r--src/libstd/unstable/intrinsics.rs132
-rw-r--r--src/libstd/vec.rs15
11 files changed, 217 insertions, 80 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index b871ed3d57a..5a2f948600a 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -25,13 +25,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);
     }
@@ -197,6 +200,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;
@@ -258,7 +265,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..ee9fdd3c620 100644
--- a/src/libstd/cleanup.rs
+++ b/src/libstd/cleanup.rs
@@ -10,24 +10,19 @@
 
 #[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};
 use repr::BoxRepr;
-use sys::TypeDesc;
 use cast::transmute;
+use unstable::intrinsics::TyDesc;
 #[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 +159,19 @@ fn debug_mem() -> bool {
     false
 }
 
+#[inline]
+#[cfg(not(stage0))]
+unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
+    // This function should be inlined when stage0 is gone
+    ((*tydesc).drop_glue)(data);
+}
+
+#[inline]
+#[cfg(stage0)]
+unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
+    ((*tydesc).drop_glue)(0 as **TyDesc, data);
+}
+
 /// Destroys all managed memory (i.e. @ boxes) held by the current task.
 #[cfg(not(test))]
 #[lang="annihilate"]
@@ -205,9 +213,9 @@ 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));
+            let tydesc = (*box).header.type_desc;
+            let data = transmute(&(*box).data);
+            call_drop_glue(tydesc, data);
         }
     }
 
diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs
index 611b95a7745..c9e33219fa5 100644
--- a/src/libstd/gc.rs
+++ b/src/libstd/gc.rs
@@ -40,12 +40,13 @@ with destructors.
 use cast;
 use container::{Map, Set};
 use io;
-use libc::{size_t, uintptr_t};
+use libc::{uintptr_t};
 use option::{None, Option, Some};
 use ptr;
 use hashmap::HashSet;
 use stackwalk::walk_stack;
 use sys;
+use unstable::intrinsics::{TyDesc};
 
 pub use stackwalk::Word;
 
@@ -58,18 +59,12 @@ pub struct StackSegment {
 }
 
 pub mod rustrt {
-    use libc::size_t;
     use stackwalk::Word;
     use super::StackSegment;
 
     #[link_name = "rustrt"]
     pub extern {
         #[rust_stack]
-        pub unsafe fn rust_call_tydesc_glue(root: *Word,
-                                            tydesc: *Word,
-                                            field: size_t);
-
-        #[rust_stack]
         pub unsafe fn rust_gc_metadata() -> *Word;
 
         pub unsafe fn rust_get_stack_segment() -> *StackSegment;
@@ -125,7 +120,7 @@ unsafe fn is_safe_point(pc: *Word) -> Option<SafePoint> {
     return None;
 }
 
-type Visitor<'self> = &'self fn(root: **Word, tydesc: *Word) -> bool;
+type Visitor<'self> = &'self fn(root: **Word, tydesc: *TyDesc) -> bool;
 
 // Walks the list of roots for the given safe point, and calls visitor
 // on each root.
@@ -139,7 +134,7 @@ unsafe fn _walk_safe_point(fp: *Word, sp: SafePoint, visitor: Visitor) -> bool {
     let stack_roots: *u32 = bump(sp_meta, 2);
     let reg_roots: *u8 = bump(stack_roots, num_stack_roots);
     let addrspaces: *Word = align_to_pointer(bump(reg_roots, num_reg_roots));
-    let tydescs: ***Word = bump(addrspaces, num_stack_roots);
+    let tydescs: ***TyDesc = bump(addrspaces, num_stack_roots);
 
     // Stack roots
     let mut sri = 0;
@@ -321,6 +316,19 @@ fn expect_sentinel() -> bool { true }
 #[cfg(nogc)]
 fn expect_sentinel() -> bool { false }
 
+#[inline]
+#[cfg(not(stage0))]
+unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
+    // This function should be inlined when stage0 is gone
+    ((*tydesc).drop_glue)(data);
+}
+
+#[inline]
+#[cfg(stage0)]
+unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
+    ((*tydesc).drop_glue)(0 as **TyDesc, data);
+}
+
 // Entry point for GC-based cleanup. Walks stack looking for exchange
 // heap and stack allocations requiring drop, and runs all
 // destructors.
@@ -364,7 +372,7 @@ pub fn cleanup_stack_for_failure() {
                 // FIXME #4420: Destroy this box
                 // FIXME #4330: Destroy this box
             } else {
-                rustrt::rust_call_tydesc_glue(*root, tydesc, 3 as size_t);
+                call_drop_glue(tydesc, *root as *i8);
             }
         }
     }
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..a1d6342323c 100644
--- a/src/libstd/sys.rs
+++ b/src/libstd/sys.rs
@@ -17,23 +17,11 @@ 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
-pub struct TypeDesc {
-    size: uint,
-    align: uint,
-    take_glue: uint,
-    drop_glue: uint,
-    free_glue: uint
-    // Remaining fields not listed
-}
-
 /// The representation of a Rust closure
 pub struct Closure {
     code: *(),
@@ -51,23 +39,6 @@ pub mod rustrt {
     }
 }
 
-/**
- * Returns a pointer to a type descriptor.
- *
- * Useful for calling certain function in the Rust runtime or otherwise
- * performing dark magick.
- */
-#[inline]
-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 109f665e41d..1254a591293 100644
--- a/src/libstd/unstable/intrinsics.rs
+++ b/src/libstd/unstable/intrinsics.rs
@@ -32,6 +32,130 @@ 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};
+
+#[cfg(not(stage0))]
+pub type GlueFn = extern "Rust" fn(*i8);
+
+#[cfg(stage0)]
+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,
+}
+
+#[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" {
 
@@ -159,6 +283,9 @@ pub extern "rust-intrinsic" {
     pub fn pref_align_of<T>() -> uint;
 
     /// Get a static pointer to a type descriptor.
+    #[cfg(not(stage0))]
+    pub fn get_tydesc<T>() -> *TyDesc;
+    #[cfg(stage0)]
     pub fn get_tydesc<T>() -> *();
 
     /// Create a value initialized to zero.
@@ -181,9 +308,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 e39dd262cd9..72b58307849 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -30,6 +30,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;
 
@@ -37,19 +41,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);
     }
@@ -78,7 +85,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);