summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-06-03 19:11:49 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-06-06 22:19:41 -0700
commit5ec36c358f74fe83332231e774ea20a21d165120 (patch)
tree290670162c10365e09f24562d68b88fb92275c51 /src/libstd
parenta3f9aa9ef8657304006fcbe4759a263720b8592c (diff)
downloadrust-5ec36c358f74fe83332231e774ea20a21d165120.tar.gz
rust-5ec36c358f74fe83332231e774ea20a21d165120.zip
std: Extract librustrt out of libstd
As part of the libstd facade efforts, this commit extracts the runtime interface
out of the standard library into a standalone crate, librustrt. This crate will
provide the following services:

* Definition of the rtio interface
* Definition of the Runtime interface
* Implementation of the Task structure
* Implementation of task-local-data
* Implementation of task failure via unwinding via libunwind
* Implementation of runtime initialization and shutdown
* Implementation of thread-local-storage for the local rust Task

Notably, this crate avoids the following services:

* Thread creation and destruction. The crate does not require the knowledge of
  an OS threading system, and as a result it seemed best to leave out the
  `rt::thread` module from librustrt. The librustrt module does depend on
  mutexes, however.
* Implementation of backtraces. There is no inherent requirement for the runtime
  to be able to generate backtraces. As will be discussed later, this
  functionality continues to live in libstd rather than librustrt.

As usual, a number of architectural changes were required to make this crate
possible. Users of "stable" functionality will not be impacted by this change,
but users of the `std::rt` module will likely note the changes. A list of
architectural changes made is:

* The stdout/stderr handles no longer live directly inside of the `Task`
  structure. This is a consequence of librustrt not knowing about `std::io`.
  These two handles are now stored inside of task-local-data.

  The handles were originally stored inside of the `Task` for perf reasons, and
  TLD is not currently as fast as it could be. For comparison, 100k prints goes
  from 59ms to 68ms (a 15% slowdown). This appeared to me to be an acceptable
  perf loss for the successful extraction of a librustrt crate.

* The `rtio` module was forced to duplicate more functionality of `std::io`. As
  the module no longer depends on `std::io`, `rtio` now defines structures such
  as socket addresses, addrinfo fiddly bits, etc. The primary change made was
  that `rtio` now defines its own `IoError` type. This type is distinct from
  `std::io::IoError` in that it does not have an enum for what error occurred,
  but rather a platform-specific error code.

  The native and green libraries will be updated in later commits for this
  change, and the bulk of this effort was put behind updating the two libraries
  for this change (with `rtio`).

* Printing a message on task failure (along with the backtrace) continues to
  live in libstd, not in librustrt. This is a consequence of the above decision
  to move the stdout/stderr handles to TLD rather than inside the `Task` itself.
  The unwinding API now supports registration of global callback functions which
  will be invoked when a task fails, allowing for libstd to register a function
  to print a message and a backtrace.

  The API for registering a callback is experimental and unsafe, as the
  ramifications of running code on unwinding is pretty hairy.

* The `std::unstable::mutex` module has moved to `std::rt::mutex`.

* The `std::unstable::sync` module has been moved to `std::rt::exclusive` and
  the type has been rewritten to not internally have an Arc and to have an RAII
  guard structure when locking. Old code should stop using `Exclusive` in favor
  of the primitives in `libsync`, but if necessary, old code should port to
  `Arc<Exclusive<T>>`.

* The local heap has been stripped down to have fewer debugging options. None of
  these were tested, and none of these have been used in a very long time.

[breaking-change]
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/c_str.rs817
-rw-r--r--src/libstd/cleanup.rs102
-rw-r--r--src/libstd/failure.rs102
-rw-r--r--src/libstd/local_data.rs436
-rw-r--r--src/libstd/rt/args.rs172
-rw-r--r--src/libstd/rt/at_exit_imp.rs74
-rw-r--r--src/libstd/rt/backtrace.rs103
-rw-r--r--src/libstd/rt/bookkeeping.rs52
-rw-r--r--src/libstd/rt/env.rs61
-rw-r--r--src/libstd/rt/libunwind.rs163
-rw-r--r--src/libstd/rt/local.rs132
-rw-r--r--src/libstd/rt/local_heap.rs339
-rw-r--r--src/libstd/rt/local_ptr.rs404
-rw-r--r--src/libstd/rt/macros.rs49
-rw-r--r--src/libstd/rt/mod.rs150
-rw-r--r--src/libstd/rt/rtio.rs361
-rw-r--r--src/libstd/rt/stack.rs279
-rw-r--r--src/libstd/rt/task.rs500
-rw-r--r--src/libstd/rt/thread_local_storage.rs112
-rw-r--r--src/libstd/rt/unwind.rs494
-rw-r--r--src/libstd/rt/util.rs148
-rw-r--r--src/libstd/unstable/mutex.rs629
-rw-r--r--src/libstd/unstable/sync.rs159
23 files changed, 245 insertions, 5593 deletions
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
deleted file mode 100644
index 4e39518deb4..00000000000
--- a/src/libstd/c_str.rs
+++ /dev/null
@@ -1,817 +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.
-
-/*!
-
-C-string manipulation and management
-
-This modules provides the basic methods for creating and manipulating
-null-terminated strings for use with FFI calls (back to C). Most C APIs require
-that the string being passed to them is null-terminated, and by default rust's
-string types are *not* null terminated.
-
-The other problem with translating Rust strings to C strings is that Rust
-strings can validly contain a null-byte in the middle of the string (0 is a
-valid unicode codepoint). This means that not all Rust strings can actually be
-translated to C strings.
-
-# Creation of a C string
-
-A C string is managed through the `CString` type defined in this module. It
-"owns" the internal buffer of characters and will automatically deallocate the
-buffer when the string is dropped. The `ToCStr` trait is implemented for `&str`
-and `&[u8]`, but the conversions can fail due to some of the limitations
-explained above.
-
-This also means that currently whenever a C string is created, an allocation
-must be performed to place the data elsewhere (the lifetime of the C string is
-not tied to the lifetime of the original string/data buffer). If C strings are
-heavily used in applications, then caching may be advisable to prevent
-unnecessary amounts of allocations.
-
-An example of creating and using a C string would be:
-
-```rust
-extern crate libc;
-
-extern {
-    fn puts(s: *libc::c_char);
-}
-
-fn main() {
-    let my_string = "Hello, world!";
-
-    // Allocate the C string with an explicit local that owns the string. The
-    // `c_buffer` pointer will be deallocated when `my_c_string` goes out of scope.
-    let my_c_string = my_string.to_c_str();
-    my_c_string.with_ref(|c_buffer| {
-        unsafe { puts(c_buffer); }
-    });
-
-    // Don't save off the allocation of the C string, the `c_buffer` will be
-    // deallocated when this block returns!
-    my_string.with_c_str(|c_buffer| {
-        unsafe { puts(c_buffer); }
-    });
-}
-```
-
-*/
-
-use clone::Clone;
-use cmp::PartialEq;
-use container::Container;
-use iter::{Iterator, range};
-use kinds::marker;
-use libc;
-use mem;
-use ops::Drop;
-use option::{Option, Some, None};
-use ptr::RawPtr;
-use ptr;
-use raw::Slice;
-use rt::libc_heap::malloc_raw;
-use slice::{ImmutableVector, MutableVector};
-use slice;
-use str::StrSlice;
-use str;
-use string::String;
-
-/// The representation of a C String.
-///
-/// This structure wraps a `*libc::c_char`, and will automatically free the
-/// memory it is pointing to when it goes out of scope.
-pub struct CString {
-    buf: *libc::c_char,
-    owns_buffer_: bool,
-}
-
-impl Clone for CString {
-    /// Clone this CString into a new, uniquely owned CString. For safety
-    /// reasons, this is always a deep clone, rather than the usual shallow
-    /// clone.
-    fn clone(&self) -> CString {
-        if self.buf.is_null() {
-            CString { buf: self.buf, owns_buffer_: self.owns_buffer_ }
-        } else {
-            let len = self.len() + 1;
-            let buf = unsafe { malloc_raw(len) } as *mut libc::c_char;
-            unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
-            CString { buf: buf as *libc::c_char, owns_buffer_: true }
-        }
-    }
-}
-
-impl PartialEq for CString {
-    fn eq(&self, other: &CString) -> bool {
-        if self.buf as uint == other.buf as uint {
-            true
-        } else if self.buf.is_null() || other.buf.is_null() {
-            false
-        } else {
-            unsafe {
-                libc::strcmp(self.buf, other.buf) == 0
-            }
-        }
-    }
-}
-
-impl CString {
-    /// Create a C String from a pointer.
-    pub unsafe fn new(buf: *libc::c_char, owns_buffer: bool) -> CString {
-        CString { buf: buf, owns_buffer_: owns_buffer }
-    }
-
-    /// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
-    /// Any ownership of the buffer by the `CString` wrapper is forgotten.
-    pub unsafe fn unwrap(self) -> *libc::c_char {
-        let mut c_str = self;
-        c_str.owns_buffer_ = false;
-        c_str.buf
-    }
-
-    /// Calls a closure with a reference to the underlying `*libc::c_char`.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    pub fn with_ref<T>(&self, f: |*libc::c_char| -> T) -> T {
-        if self.buf.is_null() { fail!("CString is null!"); }
-        f(self.buf)
-    }
-
-    /// Calls a closure with a mutable reference to the underlying `*libc::c_char`.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    pub fn with_mut_ref<T>(&mut self, f: |*mut libc::c_char| -> T) -> T {
-        if self.buf.is_null() { fail!("CString is null!"); }
-        f(self.buf as *mut libc::c_char)
-    }
-
-    /// Returns true if the CString is a null.
-    pub fn is_null(&self) -> bool {
-        self.buf.is_null()
-    }
-
-    /// Returns true if the CString is not null.
-    pub fn is_not_null(&self) -> bool {
-        self.buf.is_not_null()
-    }
-
-    /// Returns whether or not the `CString` owns the buffer.
-    pub fn owns_buffer(&self) -> bool {
-        self.owns_buffer_
-    }
-
-    /// Converts the CString into a `&[u8]` without copying.
-    /// Includes the terminating NUL byte.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    #[inline]
-    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
-        if self.buf.is_null() { fail!("CString is null!"); }
-        unsafe {
-            mem::transmute(Slice { data: self.buf, len: self.len() + 1 })
-        }
-    }
-
-    /// Converts the CString into a `&[u8]` without copying.
-    /// Does not include the terminating NUL byte.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    #[inline]
-    pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
-        if self.buf.is_null() { fail!("CString is null!"); }
-        unsafe {
-            mem::transmute(Slice { data: self.buf, len: self.len() })
-        }
-    }
-
-    /// Converts the CString into a `&str` without copying.
-    /// Returns None if the CString is not UTF-8.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    #[inline]
-    pub fn as_str<'a>(&'a self) -> Option<&'a str> {
-        let buf = self.as_bytes_no_nul();
-        str::from_utf8(buf)
-    }
-
-    /// Return a CString iterator.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    pub fn iter<'a>(&'a self) -> CChars<'a> {
-        if self.buf.is_null() { fail!("CString is null!"); }
-        CChars {
-            ptr: self.buf,
-            marker: marker::ContravariantLifetime,
-        }
-    }
-}
-
-impl Drop for CString {
-    fn drop(&mut self) {
-        if self.owns_buffer_ {
-            unsafe {
-                libc::free(self.buf as *mut libc::c_void)
-            }
-        }
-    }
-}
-
-impl Container for CString {
-    /// Return the number of bytes in the CString (not including the NUL terminator).
-    ///
-    /// # Failure
-    ///
-    /// Fails if the CString is null.
-    #[inline]
-    fn len(&self) -> uint {
-        if self.buf.is_null() { fail!("CString is null!"); }
-        unsafe {
-            ptr::position(self.buf, |c| *c == 0)
-        }
-    }
-}
-
-/// A generic trait for converting a value to a CString.
-pub trait ToCStr {
-    /// Copy the receiver into a CString.
-    ///
-    /// # Failure
-    ///
-    /// Fails the task if the receiver has an interior null.
-    fn to_c_str(&self) -> CString;
-
-    /// Unsafe variant of `to_c_str()` that doesn't check for nulls.
-    unsafe fn to_c_str_unchecked(&self) -> CString;
-
-    /// Work with a temporary CString constructed from the receiver.
-    /// The provided `*libc::c_char` will be freed immediately upon return.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// extern crate libc;
-    ///
-    /// fn main() {
-    ///     let s = "PATH".with_c_str(|path| unsafe {
-    ///         libc::getenv(path)
-    ///     });
-    /// }
-    /// ```
-    ///
-    /// # Failure
-    ///
-    /// Fails the task if the receiver has an interior null.
-    #[inline]
-    fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
-        self.to_c_str().with_ref(f)
-    }
-
-    /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
-    #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
-        self.to_c_str_unchecked().with_ref(f)
-    }
-}
-
-// FIXME (#12938): Until DST lands, we cannot decompose &str into &
-// and str, so we cannot usefully take ToCStr arguments by reference
-// (without forcing an additional & around &str). So we are instead
-// temporarily adding an instance for ~str and String, so that we can
-// take ToCStr as owned. When DST lands, the string instances should
-// be revisted, and arguments bound by ToCStr should be passed by
-// reference.
-
-impl<'a> ToCStr for &'a str {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        self.as_bytes().to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        self.as_bytes().to_c_str_unchecked()
-    }
-
-    #[inline]
-    fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
-        self.as_bytes().with_c_str(f)
-    }
-
-    #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
-        self.as_bytes().with_c_str_unchecked(f)
-    }
-}
-
-impl ToCStr for String {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        self.as_bytes().to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        self.as_bytes().to_c_str_unchecked()
-    }
-
-    #[inline]
-    fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
-        self.as_bytes().with_c_str(f)
-    }
-
-    #[inline]
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
-        self.as_bytes().with_c_str_unchecked(f)
-    }
-}
-
-// The length of the stack allocated buffer for `vec.with_c_str()`
-static BUF_LEN: uint = 128;
-
-impl<'a> ToCStr for &'a [u8] {
-    fn to_c_str(&self) -> CString {
-        let mut cs = unsafe { self.to_c_str_unchecked() };
-        cs.with_mut_ref(|buf| check_for_null(*self, buf));
-        cs
-    }
-
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        let self_len = self.len();
-        let buf = malloc_raw(self_len + 1);
-
-        ptr::copy_memory(buf, self.as_ptr(), self_len);
-        *buf.offset(self_len as int) = 0;
-
-        CString::new(buf as *libc::c_char, true)
-    }
-
-    fn with_c_str<T>(&self, f: |*libc::c_char| -> T) -> T {
-        unsafe { with_c_str(*self, true, f) }
-    }
-
-    unsafe fn with_c_str_unchecked<T>(&self, f: |*libc::c_char| -> T) -> T {
-        with_c_str(*self, false, f)
-    }
-}
-
-// Unsafe function that handles possibly copying the &[u8] into a stack array.
-unsafe fn with_c_str<T>(v: &[u8], checked: bool, f: |*libc::c_char| -> T) -> T {
-    if v.len() < BUF_LEN {
-        let mut buf: [u8, .. BUF_LEN] = mem::uninitialized();
-        slice::bytes::copy_memory(buf, v);
-        buf[v.len()] = 0;
-
-        let buf = buf.as_mut_ptr();
-        if checked {
-            check_for_null(v, buf as *mut libc::c_char);
-        }
-
-        f(buf as *libc::c_char)
-    } else if checked {
-        v.to_c_str().with_ref(f)
-    } else {
-        v.to_c_str_unchecked().with_ref(f)
-    }
-}
-
-#[inline]
-fn check_for_null(v: &[u8], buf: *mut libc::c_char) {
-    for i in range(0, v.len()) {
-        unsafe {
-            let p = buf.offset(i as int);
-            assert!(*p != 0);
-        }
-    }
-}
-
-/// External iterator for a CString's bytes.
-///
-/// Use with the `std::iter` module.
-pub struct CChars<'a> {
-    ptr: *libc::c_char,
-    marker: marker::ContravariantLifetime<'a>,
-}
-
-impl<'a> Iterator<libc::c_char> for CChars<'a> {
-    fn next(&mut self) -> Option<libc::c_char> {
-        let ch = unsafe { *self.ptr };
-        if ch == 0 {
-            None
-        } else {
-            self.ptr = unsafe { self.ptr.offset(1) };
-            Some(ch)
-        }
-    }
-}
-
-/// Parses a C "multistring", eg windows env values or
-/// the req->ptr result in a uv_fs_readdir() call.
-///
-/// Optionally, a `count` can be passed in, limiting the
-/// parsing to only being done `count`-times.
-///
-/// The specified closure is invoked with each string that
-/// is found, and the number of strings found is returned.
-pub unsafe fn from_c_multistring(buf: *libc::c_char,
-                                 count: Option<uint>,
-                                 f: |&CString|) -> uint {
-
-    let mut curr_ptr: uint = buf as uint;
-    let mut ctr = 0;
-    let (limited_count, limit) = match count {
-        Some(limit) => (true, limit),
-        None => (false, 0)
-    };
-    while ((limited_count && ctr < limit) || !limited_count)
-          && *(curr_ptr as *libc::c_char) != 0 as libc::c_char {
-        let cstr = CString::new(curr_ptr as *libc::c_char, false);
-        f(&cstr);
-        curr_ptr += cstr.len() + 1;
-        ctr += 1;
-    }
-    return ctr;
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use super::*;
-    use libc;
-    use ptr;
-    use str::StrSlice;
-
-    #[test]
-    fn test_str_multistring_parsing() {
-        unsafe {
-            let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
-            let ptr = input.as_ptr();
-            let expected = ["zero", "one"];
-            let mut it = expected.iter();
-            let result = from_c_multistring(ptr as *libc::c_char, None, |c| {
-                let cbytes = c.as_bytes_no_nul();
-                assert_eq!(cbytes, it.next().unwrap().as_bytes());
-            });
-            assert_eq!(result, 2);
-            assert!(it.next().is_none());
-        }
-    }
-
-    #[test]
-    fn test_str_to_c_str() {
-        "".to_c_str().with_ref(|buf| {
-            unsafe {
-                assert_eq!(*buf.offset(0), 0);
-            }
-        });
-
-        "hello".to_c_str().with_ref(|buf| {
-            unsafe {
-                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
-                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
-                assert_eq!(*buf.offset(2), 'l' as libc::c_char);
-                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
-                assert_eq!(*buf.offset(4), 'o' as libc::c_char);
-                assert_eq!(*buf.offset(5), 0);
-            }
-        })
-    }
-
-    #[test]
-    fn test_vec_to_c_str() {
-        let b: &[u8] = [];
-        b.to_c_str().with_ref(|buf| {
-            unsafe {
-                assert_eq!(*buf.offset(0), 0);
-            }
-        });
-
-        let _ = bytes!("hello").to_c_str().with_ref(|buf| {
-            unsafe {
-                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
-                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
-                assert_eq!(*buf.offset(2), 'l' as libc::c_char);
-                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
-                assert_eq!(*buf.offset(4), 'o' as libc::c_char);
-                assert_eq!(*buf.offset(5), 0);
-            }
-        });
-
-        let _ = bytes!("foo", 0xff).to_c_str().with_ref(|buf| {
-            unsafe {
-                assert_eq!(*buf.offset(0), 'f' as libc::c_char);
-                assert_eq!(*buf.offset(1), 'o' as libc::c_char);
-                assert_eq!(*buf.offset(2), 'o' as libc::c_char);
-                assert_eq!(*buf.offset(3), 0xff as i8);
-                assert_eq!(*buf.offset(4), 0);
-            }
-        });
-    }
-
-    #[test]
-    fn test_is_null() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        assert!(c_str.is_null());
-        assert!(!c_str.is_not_null());
-    }
-
-    #[test]
-    fn test_unwrap() {
-        let c_str = "hello".to_c_str();
-        unsafe { libc::free(c_str.unwrap() as *mut libc::c_void) }
-    }
-
-    #[test]
-    fn test_with_ref() {
-        let c_str = "hello".to_c_str();
-        let len = unsafe { c_str.with_ref(|buf| libc::strlen(buf)) };
-        assert!(!c_str.is_null());
-        assert!(c_str.is_not_null());
-        assert_eq!(len, 5);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_with_ref_empty_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        c_str.with_ref(|_| ());
-    }
-
-    #[test]
-    fn test_iterator() {
-        let c_str = "".to_c_str();
-        let mut iter = c_str.iter();
-        assert_eq!(iter.next(), None);
-
-        let c_str = "hello".to_c_str();
-        let mut iter = c_str.iter();
-        assert_eq!(iter.next(), Some('h' as libc::c_char));
-        assert_eq!(iter.next(), Some('e' as libc::c_char));
-        assert_eq!(iter.next(), Some('l' as libc::c_char));
-        assert_eq!(iter.next(), Some('l' as libc::c_char));
-        assert_eq!(iter.next(), Some('o' as libc::c_char));
-        assert_eq!(iter.next(), None);
-    }
-
-    #[test]
-    fn test_to_c_str_fail() {
-        use task;
-        assert!(task::try(proc() { "he\x00llo".to_c_str() }).is_err());
-    }
-
-    #[test]
-    fn test_to_c_str_unchecked() {
-        unsafe {
-            "he\x00llo".to_c_str_unchecked().with_ref(|buf| {
-                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
-                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
-                assert_eq!(*buf.offset(2), 0);
-                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
-                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
-                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
-                assert_eq!(*buf.offset(6), 0);
-            })
-        }
-    }
-
-    #[test]
-    fn test_as_bytes() {
-        let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_bytes(), bytes!("hello", 0));
-        let c_str = "".to_c_str();
-        assert_eq!(c_str.as_bytes(), bytes!(0));
-        let c_str = bytes!("foo", 0xff).to_c_str();
-        assert_eq!(c_str.as_bytes(), bytes!("foo", 0xff, 0));
-    }
-
-    #[test]
-    fn test_as_bytes_no_nul() {
-        let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_bytes_no_nul(), bytes!("hello"));
-        let c_str = "".to_c_str();
-        let exp: &[u8] = [];
-        assert_eq!(c_str.as_bytes_no_nul(), exp);
-        let c_str = bytes!("foo", 0xff).to_c_str();
-        assert_eq!(c_str.as_bytes_no_nul(), bytes!("foo", 0xff));
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_as_bytes_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        c_str.as_bytes();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_as_bytes_no_nul_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        c_str.as_bytes_no_nul();
-    }
-
-    #[test]
-    fn test_as_str() {
-        let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_str(), Some("hello"));
-        let c_str = "".to_c_str();
-        assert_eq!(c_str.as_str(), Some(""));
-        let c_str = bytes!("foo", 0xff).to_c_str();
-        assert_eq!(c_str.as_str(), None);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_as_str_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        c_str.as_str();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_len_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        c_str.len();
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_iter_fail() {
-        let c_str = unsafe { CString::new(ptr::null(), false) };
-        c_str.iter();
-    }
-
-    #[test]
-    fn test_clone() {
-        let a = "hello".to_c_str();
-        let b = a.clone();
-        assert!(a == b);
-    }
-
-    #[test]
-    fn test_clone_noleak() {
-        fn foo(f: |c: &CString|) {
-            let s = "test".to_string();
-            let c = s.to_c_str();
-            // give the closure a non-owned CString
-            let mut c_ = c.with_ref(|c| unsafe { CString::new(c, false) } );
-            f(&c_);
-            // muck with the buffer for later printing
-            c_.with_mut_ref(|c| unsafe { *c = 'X' as libc::c_char } );
-        }
-
-        let mut c_: Option<CString> = None;
-        foo(|c| {
-            c_ = Some(c.clone());
-            c.clone();
-            // force a copy, reading the memory
-            c.as_bytes().to_owned();
-        });
-        let c_ = c_.unwrap();
-        // force a copy, reading the memory
-        c_.as_bytes().to_owned();
-    }
-
-    #[test]
-    fn test_clone_eq_null() {
-        let x = unsafe { CString::new(ptr::null(), false) };
-        let y = x.clone();
-        assert!(x == y);
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-    use libc;
-    use prelude::*;
-
-    #[inline]
-    fn check(s: &str, c_str: *libc::c_char) {
-        let s_buf = s.as_ptr();
-        for i in range(0, s.len()) {
-            unsafe {
-                assert_eq!(
-                    *s_buf.offset(i as int) as libc::c_char,
-                    *c_str.offset(i as int));
-            }
-        }
-    }
-
-    static s_short: &'static str = "Mary";
-    static s_medium: &'static str = "Mary had a little lamb";
-    static s_long: &'static str = "\
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb";
-
-    fn bench_to_str(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            let c_str = s.to_c_str();
-            c_str.with_ref(|c_str_buf| check(s, c_str_buf))
-        })
-    }
-
-    #[bench]
-    fn bench_to_c_str_short(b: &mut Bencher) {
-        bench_to_str(b, s_short)
-    }
-
-    #[bench]
-    fn bench_to_c_str_medium(b: &mut Bencher) {
-        bench_to_str(b, s_medium)
-    }
-
-    #[bench]
-    fn bench_to_c_str_long(b: &mut Bencher) {
-        bench_to_str(b, s_long)
-    }
-
-    fn bench_to_c_str_unchecked(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            let c_str = unsafe { s.to_c_str_unchecked() };
-            c_str.with_ref(|c_str_buf| check(s, c_str_buf))
-        })
-    }
-
-    #[bench]
-    fn bench_to_c_str_unchecked_short(b: &mut Bencher) {
-        bench_to_c_str_unchecked(b, s_short)
-    }
-
-    #[bench]
-    fn bench_to_c_str_unchecked_medium(b: &mut Bencher) {
-        bench_to_c_str_unchecked(b, s_medium)
-    }
-
-    #[bench]
-    fn bench_to_c_str_unchecked_long(b: &mut Bencher) {
-        bench_to_c_str_unchecked(b, s_long)
-    }
-
-    fn bench_with_c_str(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            s.with_c_str(|c_str_buf| check(s, c_str_buf))
-        })
-    }
-
-    #[bench]
-    fn bench_with_c_str_short(b: &mut Bencher) {
-        bench_with_c_str(b, s_short)
-    }
-
-    #[bench]
-    fn bench_with_c_str_medium(b: &mut Bencher) {
-        bench_with_c_str(b, s_medium)
-    }
-
-    #[bench]
-    fn bench_with_c_str_long(b: &mut Bencher) {
-        bench_with_c_str(b, s_long)
-    }
-
-    fn bench_with_c_str_unchecked(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            unsafe {
-                s.with_c_str_unchecked(|c_str_buf| check(s, c_str_buf))
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_with_c_str_unchecked_short(b: &mut Bencher) {
-        bench_with_c_str_unchecked(b, s_short)
-    }
-
-    #[bench]
-    fn bench_with_c_str_unchecked_medium(b: &mut Bencher) {
-        bench_with_c_str_unchecked(b, s_medium)
-    }
-
-    #[bench]
-    fn bench_with_c_str_unchecked_long(b: &mut Bencher) {
-        bench_with_c_str_unchecked(b, s_long)
-    }
-}
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs
deleted file mode 100644
index 2e51931f15a..00000000000
--- a/src/libstd/cleanup.rs
+++ /dev/null
@@ -1,102 +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.
-
-#![doc(hidden)]
-
-use ptr;
-use raw;
-
-static RC_IMMORTAL : uint = 0x77777777;
-
-/*
- * Box annihilation
- *
- * This runs at task death to free all boxes.
- */
-
-unsafe fn each_live_alloc(read_next_before: bool,
-                          f: |alloc: *mut raw::Box<()>| -> bool)
-                          -> bool {
-    //! Walks the internal list of allocations
-
-    use rt::local_heap;
-
-    let mut alloc = local_heap::live_allocs();
-    while alloc != ptr::mut_null() {
-        let next_before = (*alloc).next;
-
-        if !f(alloc) {
-            return false;
-        }
-
-        if read_next_before {
-            alloc = next_before;
-        } else {
-            alloc = (*alloc).next;
-        }
-    }
-    return true;
-}
-
-#[cfg(unix)]
-fn debug_mem() -> bool {
-    // FIXME: Need to port the environment struct to newsched
-    false
-}
-
-#[cfg(windows)]
-fn debug_mem() -> bool {
-    false
-}
-
-/// Destroys all managed memory (i.e. @ boxes) held by the current task.
-pub unsafe fn annihilate() {
-    use rt::local_heap::local_free;
-
-    let mut n_total_boxes = 0u;
-
-    // Pass 1: Make all boxes immortal.
-    //
-    // In this pass, nothing gets freed, so it does not matter whether
-    // we read the next field before or after the callback.
-    each_live_alloc(true, |alloc| {
-        n_total_boxes += 1;
-        (*alloc).ref_count = RC_IMMORTAL;
-        true
-    });
-
-    // Pass 2: Drop all boxes.
-    //
-    // In this pass, unique-managed boxes may get freed, but not
-    // managed boxes, so we must read the `next` field *after* the
-    // callback, as the original value may have been freed.
-    each_live_alloc(false, |alloc| {
-        let drop_glue = (*alloc).drop_glue;
-        let data = &mut (*alloc).data as *mut ();
-        drop_glue(data as *mut u8);
-        true
-    });
-
-    // Pass 3: Free all boxes.
-    //
-    // In this pass, managed boxes may get freed (but not
-    // unique-managed boxes, though I think that none of those are
-    // left), so we must read the `next` field before, since it will
-    // not be valid after.
-    each_live_alloc(true, |alloc| {
-        local_free(alloc as *u8);
-        true
-    });
-
-    if debug_mem() {
-        // We do logging here w/o allocation.
-        println!("total boxes annihilated: {}", n_total_boxes);
-    }
-}
diff --git a/src/libstd/failure.rs b/src/libstd/failure.rs
new file mode 100644
index 00000000000..903f39c7b06
--- /dev/null
+++ b/src/libstd/failure.rs
@@ -0,0 +1,102 @@
+// Copyright 2014 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 alloc::owned::Box;
+use any::{Any, AnyRefExt};
+use fmt;
+use io::{Writer, IoResult};
+use kinds::Send;
+use option::{Some, None};
+use result::Ok;
+use rt::backtrace;
+use rt::{Stderr, Stdio};
+use rustrt::local::Local;
+use rustrt::task::Task;
+use str::Str;
+use string::String;
+
+// Defined in this module instead of io::stdio so that the unwinding
+local_data_key!(pub local_stderr: Box<Writer:Send>)
+
+impl Writer for Stdio {
+    fn write(&mut self, bytes: &[u8]) -> IoResult<()> {
+        fn fmt_write<F: fmt::FormatWriter>(f: &mut F, bytes: &[u8]) {
+            let _ = f.write(bytes);
+        }
+        fmt_write(self, bytes);
+        Ok(())
+    }
+}
+
+pub fn on_fail(obj: &Any:Send, file: &'static str, line: uint) {
+    let msg = match obj.as_ref::<&'static str>() {
+        Some(s) => *s,
+        None => match obj.as_ref::<String>() {
+            Some(s) => s.as_slice(),
+            None => "Box<Any>",
+        }
+    };
+    let mut err = Stderr;
+
+    // It is assumed that all reasonable rust code will have a local task at
+    // all times. This means that this `exists` will return true almost all of
+    // the time. There are border cases, however, when the runtime has
+    // *almost* set up the local task, but hasn't quite gotten there yet. In
+    // order to get some better diagnostics, we print on failure and
+    // immediately abort the whole process if there is no local task
+    // available.
+    if !Local::exists(None::<Task>) {
+        let _ = writeln!(&mut err, "failed at '{}', {}:{}", msg, file, line);
+        if backtrace::log_enabled() {
+            let _ = backtrace::write(&mut err);
+        } else {
+            let _ = writeln!(&mut err, "run with `RUST_BACKTRACE=1` to \
+                                        see a backtrace");
+        }
+        return
+    }
+
+    // Peel the name out of local task so we can print it. We've got to be sure
+    // that the local task is in TLS while we're printing as I/O may occur.
+    let (name, unwinding) = {
+        let mut t = Local::borrow(None::<Task>);
+        (t.name.take(), t.unwinder.unwinding())
+    };
+    {
+        let n = name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
+
+        match local_stderr.replace(None) {
+            Some(mut stderr) => {
+                // FIXME: what to do when the task printing fails?
+                let _ = writeln!(stderr,
+                                 "task '{}' failed at '{}', {}:{}\n",
+                                 n, msg, file, line);
+                if backtrace::log_enabled() {
+                    let _ = backtrace::write(stderr);
+                }
+                local_stderr.replace(Some(stderr));
+            }
+            None => {
+                let _ = writeln!(&mut err, "task '{}' failed at '{}', {}:{}",
+                                 n, msg, file, line);
+                if backtrace::log_enabled() {
+                    let _ = backtrace::write(&mut err);
+                }
+            }
+        }
+
+        // If this is a double failure, make sure that we printed a backtrace
+        // for this failure.
+        if unwinding && !backtrace::log_enabled() {
+            let _ = backtrace::write(&mut err);
+        }
+    }
+    Local::borrow(None::<Task>).name = name;
+}
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
deleted file mode 100644
index 930d1df02f1..00000000000
--- a/src/libstd/local_data.rs
+++ /dev/null
@@ -1,436 +0,0 @@
-// Copyright 2012-2013 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.
-
-/*!
-
-Task local data management
-
-Allows storing arbitrary types inside task-local-storage (TLS), to be accessed
-anywhere within a task, keyed by a global pointer parameterized over the type of
-the TLS slot.  Useful for dynamic variables, singletons, and interfacing with
-foreign code with bad callback interfaces.
-
-To declare a new key for storing local data of a particular type, use the
-`local_data_key!` macro. This macro will expand to a `static` item appropriately
-named and annotated. This name is then passed to the functions in this module to
-modify/read the slot specified by the key.
-
-```rust
-local_data_key!(key_int: int)
-local_data_key!(key_vector: ~[int])
-
-key_int.replace(Some(3));
-assert_eq!(*key_int.get().unwrap(), 3);
-
-key_vector.replace(Some(~[4]));
-assert_eq!(*key_vector.get().unwrap(), ~[4]);
-```
-
-*/
-
-// Casting 'Arcane Sight' reveals an overwhelming aura of Transmutation
-// magic.
-
-use iter::{Iterator};
-use kinds::Send;
-use kinds::marker;
-use mem::replace;
-use mem;
-use ops::{Drop, Deref};
-use option::{None, Option, Some};
-use owned::Box;
-use raw;
-use rt::task::{Task, LocalStorage};
-use slice::{ImmutableVector, MutableVector};
-use vec::Vec;
-
-/**
- * Indexes a task-local data slot. This pointer is used for comparison to
- * differentiate keys from one another. The actual type `T` is not used anywhere
- * as a member of this type, except that it is parameterized with it to define
- * the type of each key's value.
- *
- * The value of each Key is of the singleton enum KeyValue. These also have the
- * same name as `Key` and their purpose is to take up space in the programs data
- * sections to ensure that each value of the `Key` type points to a unique
- * location.
- */
-pub type Key<T> = &'static KeyValue<T>;
-
-#[allow(missing_doc)]
-pub enum KeyValue<T> { Key }
-
-#[doc(hidden)]
-trait LocalData {}
-impl<T: 'static> LocalData for T {}
-
-// The task-local-map stores all TLS information for the currently running task.
-// It is stored as an owned pointer into the runtime, and it's only allocated
-// when TLS is used for the first time. This map must be very carefully
-// constructed because it has many mutable loans unsoundly handed out on it to
-// the various invocations of TLS requests.
-//
-// One of the most important operations is loaning a value via `get` to a
-// caller. In doing so, the slot that the TLS entry is occupying cannot be
-// invalidated because upon returning its loan state must be updated. Currently
-// the TLS map is a vector, but this is possibly dangerous because the vector
-// can be reallocated/moved when new values are pushed onto it.
-//
-// This problem currently isn't solved in a very elegant way. Inside the `get`
-// function, it internally "invalidates" all references after the loan is
-// finished and looks up into the vector again. In theory this will prevent
-// pointers from being moved under our feet so long as LLVM doesn't go too crazy
-// with the optimizations.
-//
-// n.b. If TLS is used heavily in future, this could be made more efficient with
-//      a proper map.
-#[doc(hidden)]
-pub type Map = Vec<Option<(*u8, TLSValue, uint)>>;
-type TLSValue = Box<LocalData:Send>;
-
-// Gets the map from the runtime. Lazily initialises if not done so already.
-unsafe fn get_local_map() -> Option<&mut Map> {
-    use rt::local::Local;
-
-    if !Local::exists(None::<Task>) { return None }
-
-    let task: *mut Task = Local::unsafe_borrow();
-    match &mut (*task).storage {
-        // If the at_exit function is already set, then we just need to take
-        // a loan out on the TLS map stored inside
-        &LocalStorage(Some(ref mut map_ptr)) => {
-            return Some(map_ptr);
-        }
-        // If this is the first time we've accessed TLS, perform similar
-        // actions to the oldsched way of doing things.
-        &LocalStorage(ref mut slot) => {
-            *slot = Some(vec!());
-            match *slot {
-                Some(ref mut map_ptr) => { return Some(map_ptr) }
-                None => unreachable!(),
-            }
-        }
-    }
-}
-
-fn key_to_key_value<T: 'static>(key: Key<T>) -> *u8 {
-    key as *KeyValue<T> as *u8
-}
-
-/// An RAII immutable reference to a task-local value.
-///
-/// The task-local data can be accessed through this value, and when this
-/// structure is dropped it will return the borrow on the data.
-pub struct Ref<T> {
-    // FIXME #12808: strange names to try to avoid interfering with
-    // field accesses of the contained type via Deref
-    _ptr: &'static T,
-    _key: Key<T>,
-    _index: uint,
-    _nosend: marker::NoSend,
-}
-
-impl<T: 'static> KeyValue<T> {
-    /// Replaces a value in task local storage.
-    ///
-    /// If this key is already present in TLS, then the previous value is
-    /// replaced with the provided data, and then returned.
-    ///
-    /// # Failure
-    ///
-    /// This function will fail if this key is present in TLS and currently on
-    /// loan with the `get` method.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// local_data_key!(foo: int)
-    ///
-    /// assert_eq!(foo.replace(Some(10)), None);
-    /// assert_eq!(foo.replace(Some(4)), Some(10));
-    /// assert_eq!(foo.replace(None), Some(4));
-    /// ```
-    pub fn replace(&'static self, data: Option<T>) -> Option<T> {
-        let map = match unsafe { get_local_map() } {
-            Some(map) => map,
-            None => fail!("must have a local task to insert into TLD"),
-        };
-        let keyval = key_to_key_value(self);
-
-        // When the task-local map is destroyed, all the data needs to be
-        // cleaned up. For this reason we can't do some clever tricks to store
-        // '~T' as a '*c_void' or something like that. To solve the problem, we
-        // cast everything to a trait (LocalData) which is then stored inside
-        // the map.  Upon destruction of the map, all the objects will be
-        // destroyed and the traits have enough information about them to
-        // destroy themselves.
-        //
-        // Additionally, the type of the local data map must ascribe to Send, so
-        // we do the transmute here to add the Send bound back on. This doesn't
-        // actually matter because TLS will always own the data (until its moved
-        // out) and we're not actually sending it to other schedulers or
-        // anything.
-        let newval = data.map(|d| {
-            let d = box d as Box<LocalData>;
-            let d: Box<LocalData:Send> = unsafe { mem::transmute(d) };
-            (keyval, d, 0)
-        });
-
-        let pos = match self.find(map) {
-            Some((i, _, &0)) => Some(i),
-            Some((_, _, _)) => fail!("TLS value cannot be replaced because it \
-                                      is already borrowed"),
-            None => map.iter().position(|entry| entry.is_none()),
-        };
-
-        match pos {
-            Some(i) => {
-                replace(map.get_mut(i), newval).map(|(_, data, _)| {
-                    // Move `data` into transmute to get out the memory that it
-                    // owns, we must free it manually later.
-                    let t: raw::TraitObject = unsafe { mem::transmute(data) };
-                    let alloc: Box<T> = unsafe { mem::transmute(t.data) };
-
-                    // Now that we own `alloc`, we can just move out of it as we
-                    // would with any other data.
-                    *alloc
-                })
-            }
-            None => {
-                map.push(newval);
-                None
-            }
-        }
-    }
-
-    /// Borrows a value from TLS.
-    ///
-    /// If `None` is returned, then this key is not present in TLS. If `Some` is
-    /// returned, then the returned data is a smart pointer representing a new
-    /// loan on this TLS key. While on loan, this key cannot be altered via the
-    /// `replace` method.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// local_data_key!(key: int)
-    ///
-    /// assert!(key.get().is_none());
-    ///
-    /// key.replace(Some(3));
-    /// assert_eq!(*key.get().unwrap(), 3);
-    /// ```
-    pub fn get(&'static self) -> Option<Ref<T>> {
-        let map = match unsafe { get_local_map() } {
-            Some(map) => map,
-            None => return None,
-        };
-
-        self.find(map).map(|(pos, data, loan)| {
-            *loan += 1;
-
-            // data was created with `~T as ~LocalData`, so we extract
-            // pointer part of the trait, (as ~T), and then use
-            // compiler coercions to achieve a '&' pointer.
-            let ptr = unsafe {
-                let data = data as *Box<LocalData:Send> as *raw::TraitObject;
-                &mut *((*data).data as *mut T)
-            };
-            Ref { _ptr: ptr, _index: pos, _nosend: marker::NoSend, _key: self }
-        })
-    }
-
-    fn find<'a>(&'static self,
-                map: &'a mut Map) -> Option<(uint, &'a TLSValue, &'a mut uint)>{
-        let key_value = key_to_key_value(self);
-        map.mut_iter().enumerate().filter_map(|(i, entry)| {
-            match *entry {
-                Some((k, ref data, ref mut loan)) if k == key_value => {
-                    Some((i, data, loan))
-                }
-                _ => None
-            }
-        }).next()
-    }
-}
-
-impl<T: 'static> Deref<T> for Ref<T> {
-    fn deref<'a>(&'a self) -> &'a T { self._ptr }
-}
-
-#[unsafe_destructor]
-impl<T: 'static> Drop for Ref<T> {
-    fn drop(&mut self) {
-        let map = unsafe { get_local_map().unwrap() };
-
-        let (_, _, ref mut loan) = *map.get_mut(self._index).get_mut_ref();
-        *loan -= 1;
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use super::*;
-    use owned::Box;
-    use task;
-
-    #[test]
-    fn test_tls_multitask() {
-        static my_key: Key<String> = &Key;
-        my_key.replace(Some("parent data".to_string()));
-        task::spawn(proc() {
-            // TLS shouldn't carry over.
-            assert!(my_key.get().is_none());
-            my_key.replace(Some("child data".to_string()));
-            assert!(my_key.get().get_ref().as_slice() == "child data");
-            // should be cleaned up for us
-        });
-
-        // Must work multiple times
-        assert!(my_key.get().unwrap().as_slice() == "parent data");
-        assert!(my_key.get().unwrap().as_slice() == "parent data");
-        assert!(my_key.get().unwrap().as_slice() == "parent data");
-    }
-
-    #[test]
-    fn test_tls_overwrite() {
-        static my_key: Key<String> = &Key;
-        my_key.replace(Some("first data".to_string()));
-        my_key.replace(Some("next data".to_string())); // Shouldn't leak.
-        assert!(my_key.get().unwrap().as_slice() == "next data");
-    }
-
-    #[test]
-    fn test_tls_pop() {
-        static my_key: Key<String> = &Key;
-        my_key.replace(Some("weasel".to_string()));
-        assert!(my_key.replace(None).unwrap() == "weasel".to_string());
-        // Pop must remove the data from the map.
-        assert!(my_key.replace(None).is_none());
-    }
-
-    #[test]
-    fn test_tls_crust_automorestack_memorial_bug() {
-        // This might result in a stack-canary clobber if the runtime fails to
-        // set sp_limit to 0 when calling the cleanup extern - it might
-        // automatically jump over to the rust stack, which causes next_c_sp
-        // to get recorded as something within a rust stack segment. Then a
-        // subsequent upcall (esp. for logging, think vsnprintf) would run on
-        // a stack smaller than 1 MB.
-        static my_key: Key<String> = &Key;
-        task::spawn(proc() {
-            my_key.replace(Some("hax".to_string()));
-        });
-    }
-
-    #[test]
-    fn test_tls_multiple_types() {
-        static str_key: Key<String> = &Key;
-        static box_key: Key<@()> = &Key;
-        static int_key: Key<int> = &Key;
-        task::spawn(proc() {
-            str_key.replace(Some("string data".to_string()));
-            box_key.replace(Some(@()));
-            int_key.replace(Some(42));
-        });
-    }
-
-    #[test]
-    fn test_tls_overwrite_multiple_types() {
-        static str_key: Key<String> = &Key;
-        static box_key: Key<@()> = &Key;
-        static int_key: Key<int> = &Key;
-        task::spawn(proc() {
-            str_key.replace(Some("string data".to_string()));
-            str_key.replace(Some("string data 2".to_string()));
-            box_key.replace(Some(@()));
-            box_key.replace(Some(@()));
-            int_key.replace(Some(42));
-            // This could cause a segfault if overwriting-destruction is done
-            // with the crazy polymorphic transmute rather than the provided
-            // finaliser.
-            int_key.replace(Some(31337));
-        });
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tls_cleanup_on_failure() {
-        static str_key: Key<String> = &Key;
-        static box_key: Key<@()> = &Key;
-        static int_key: Key<int> = &Key;
-        str_key.replace(Some("parent data".to_string()));
-        box_key.replace(Some(@()));
-        task::spawn(proc() {
-            str_key.replace(Some("string data".to_string()));
-            box_key.replace(Some(@()));
-            int_key.replace(Some(42));
-            fail!();
-        });
-        // Not quite nondeterministic.
-        int_key.replace(Some(31337));
-        fail!();
-    }
-
-    #[test]
-    fn test_static_pointer() {
-        static key: Key<&'static int> = &Key;
-        static VALUE: int = 0;
-        key.replace(Some(&VALUE));
-    }
-
-    #[test]
-    fn test_owned() {
-        static key: Key<Box<int>> = &Key;
-        key.replace(Some(box 1));
-
-        {
-            let k1 = key.get().unwrap();
-            let k2 = key.get().unwrap();
-            let k3 = key.get().unwrap();
-            assert_eq!(**k1, 1);
-            assert_eq!(**k2, 1);
-            assert_eq!(**k3, 1);
-        }
-        key.replace(Some(box 2));
-        assert_eq!(**key.get().unwrap(), 2);
-    }
-
-    #[test]
-    fn test_same_key_type() {
-        static key1: Key<int> = &Key;
-        static key2: Key<int> = &Key;
-        static key3: Key<int> = &Key;
-        static key4: Key<int> = &Key;
-        static key5: Key<int> = &Key;
-        key1.replace(Some(1));
-        key2.replace(Some(2));
-        key3.replace(Some(3));
-        key4.replace(Some(4));
-        key5.replace(Some(5));
-
-        assert_eq!(*key1.get().unwrap(), 1);
-        assert_eq!(*key2.get().unwrap(), 2);
-        assert_eq!(*key3.get().unwrap(), 3);
-        assert_eq!(*key4.get().unwrap(), 4);
-        assert_eq!(*key5.get().unwrap(), 5);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_nested_get_set1() {
-        static key: Key<int> = &Key;
-        key.replace(Some(4));
-
-        let _k = key.get();
-        key.replace(Some(4));
-    }
-}
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
deleted file mode 100644
index e016c9da418..00000000000
--- a/src/libstd/rt/args.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2012-2013 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.
-
-//! Global storage for command line arguments
-//!
-//! The current incarnation of the Rust runtime expects for
-//! the processes `argc` and `argv` arguments to be stored
-//! in a globally-accessible location for use by the `os` module.
-//!
-//! Only valid to call on linux. Mac and Windows use syscalls to
-//! discover the command line arguments.
-//!
-//! FIXME #7756: Would be nice for this to not exist.
-//! FIXME #7756: This has a lot of C glue for lack of globals.
-
-use option::Option;
-use vec::Vec;
-
-/// One-time global initialization.
-pub unsafe fn init(argc: int, argv: **u8) { imp::init(argc, argv) }
-
-/// One-time global cleanup.
-pub unsafe fn cleanup() { imp::cleanup() }
-
-/// Take the global arguments from global storage.
-pub fn take() -> Option<Vec<Vec<u8>>> { imp::take() }
-
-/// Give the global arguments to global storage.
-///
-/// It is an error if the arguments already exist.
-pub fn put(args: Vec<Vec<u8>>) { imp::put(args) }
-
-/// Make a clone of the global arguments.
-pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "android")]
-#[cfg(target_os = "freebsd")]
-mod imp {
-    use clone::Clone;
-    use iter::Iterator;
-    use option::{Option, Some, None};
-    use owned::Box;
-    use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-    use mem;
-    use vec::Vec;
-    use ptr::RawPtr;
-
-    static mut global_args_ptr: uint = 0;
-    static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-
-    pub unsafe fn init(argc: int, argv: **u8) {
-        let args = load_argc_and_argv(argc, argv);
-        put(args);
-    }
-
-    pub unsafe fn cleanup() {
-        rtassert!(take().is_some());
-        lock.destroy();
-    }
-
-    pub fn take() -> Option<Vec<Vec<u8>>> {
-        with_lock(|| unsafe {
-            let ptr = get_global_ptr();
-            let val = mem::replace(&mut *ptr, None);
-            val.as_ref().map(|s: &Box<Vec<Vec<u8>>>| (**s).clone())
-        })
-    }
-
-    pub fn put(args: Vec<Vec<u8>>) {
-        with_lock(|| unsafe {
-            let ptr = get_global_ptr();
-            rtassert!((*ptr).is_none());
-            (*ptr) = Some(box args.clone());
-        })
-    }
-
-    pub fn clone() -> Option<Vec<Vec<u8>>> {
-        with_lock(|| unsafe {
-            let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s: &Box<Vec<Vec<u8>>>| (**s).clone())
-        })
-    }
-
-    fn with_lock<T>(f: || -> T) -> T {
-        unsafe {
-            let _guard = lock.lock();
-            f()
-        }
-    }
-
-    fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
-        unsafe { mem::transmute(&global_args_ptr) }
-    }
-
-    // Copied from `os`.
-    unsafe fn load_argc_and_argv(argc: int, argv: **u8) -> Vec<Vec<u8>> {
-        use c_str::CString;
-        use ptr::RawPtr;
-        use libc;
-        use vec::Vec;
-
-        Vec::from_fn(argc as uint, |i| {
-            let cs = CString::new(*(argv as **libc::c_char).offset(i as int), false);
-            Vec::from_slice(cs.as_bytes_no_nul())
-        })
-    }
-
-    #[cfg(test)]
-    mod tests {
-        use prelude::*;
-        use super::*;
-        use finally::Finally;
-
-        #[test]
-        fn smoke_test() {
-            // Preserve the actual global state.
-            let saved_value = take();
-
-            let expected = vec![
-                Vec::from_slice(bytes!("happy")),
-                Vec::from_slice(bytes!("today?")),
-            ];
-
-            put(expected.clone());
-            assert!(clone() == Some(expected.clone()));
-            assert!(take() == Some(expected.clone()));
-            assert!(take() == None);
-
-            (|| {
-            }).finally(|| {
-                // Restore the actual global state.
-                match saved_value {
-                    Some(ref args) => put(args.clone()),
-                    None => ()
-                }
-            })
-        }
-    }
-}
-
-#[cfg(target_os = "macos")]
-#[cfg(target_os = "win32")]
-mod imp {
-    use option::Option;
-    use vec::Vec;
-
-    pub unsafe fn init(_argc: int, _argv: **u8) {
-    }
-
-    pub fn cleanup() {
-    }
-
-    pub fn take() -> Option<Vec<Vec<u8>>> {
-        fail!()
-    }
-
-    pub fn put(_args: Vec<Vec<u8>>) {
-        fail!()
-    }
-
-    pub fn clone() -> Option<Vec<Vec<u8>>> {
-        fail!()
-    }
-}
diff --git a/src/libstd/rt/at_exit_imp.rs b/src/libstd/rt/at_exit_imp.rs
deleted file mode 100644
index c892a73d934..00000000000
--- a/src/libstd/rt/at_exit_imp.rs
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 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.
-
-//! Implementation of running at_exit routines
-//!
-//! Documentation can be found on the `rt::at_exit` function.
-
-use iter::Iterator;
-use kinds::Send;
-use mem;
-use option::{Some, None};
-use owned::Box;
-use ptr::RawPtr;
-use slice::OwnedVector;
-use unstable::sync::Exclusive;
-use vec::Vec;
-
-type Queue = Exclusive<Vec<proc():Send>>;
-
-// You'll note that these variables are *not* atomic, and this is done on
-// purpose. This module is designed to have init() called *once* in a
-// single-task context, and then run() is called only once in another
-// single-task context. As a result of this, only the `push` function is
-// thread-safe, and it assumes that the `init` function has run previously.
-static mut QUEUE: *mut Queue = 0 as *mut Queue;
-static mut RUNNING: bool = false;
-
-pub fn init() {
-    unsafe {
-        rtassert!(!RUNNING);
-        rtassert!(QUEUE.is_null());
-        let state: Box<Queue> = box Exclusive::new(vec!());
-        QUEUE = mem::transmute(state);
-    }
-}
-
-pub fn push(f: proc():Send) {
-    unsafe {
-        rtassert!(!RUNNING);
-        rtassert!(!QUEUE.is_null());
-        let state: &mut Queue = mem::transmute(QUEUE);
-        let mut f = Some(f);
-        state.with(|arr|  {
-            arr.push(f.take_unwrap());
-        });
-    }
-}
-
-pub fn run() {
-    let vec = unsafe {
-        rtassert!(!RUNNING);
-        rtassert!(!QUEUE.is_null());
-        RUNNING = true;
-        let state: Box<Queue> = mem::transmute(QUEUE);
-        QUEUE = 0 as *mut Queue;
-        let mut vec = None;
-        state.with(|arr| {
-            vec = Some(mem::replace(arr, vec!()));
-        });
-        vec.take_unwrap()
-    };
-
-
-    for f in vec.move_iter() {
-        f();
-    }
-}
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 94472ee7241..4229e9ad32c 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -242,8 +242,7 @@ mod imp {
     use mem;
     use option::{Some, None, Option};
     use result::{Ok, Err};
-    use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-    use uw = rt::libunwind;
+    use rt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
 
     struct Context<'a> {
         idx: int,
@@ -484,6 +483,106 @@ mod imp {
         }
         w.write(['\n' as u8])
     }
+
+    /// Unwind library interface used for backtraces
+    ///
+    /// Note that the native libraries come from librustrt, not this module.
+    #[allow(non_camel_case_types)]
+    #[allow(non_snake_case_functions)]
+    mod uw {
+        use libc;
+
+        #[repr(C)]
+        pub enum _Unwind_Reason_Code {
+            _URC_NO_REASON = 0,
+            _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
+            _URC_FATAL_PHASE2_ERROR = 2,
+            _URC_FATAL_PHASE1_ERROR = 3,
+            _URC_NORMAL_STOP = 4,
+            _URC_END_OF_STACK = 5,
+            _URC_HANDLER_FOUND = 6,
+            _URC_INSTALL_CONTEXT = 7,
+            _URC_CONTINUE_UNWIND = 8,
+            _URC_FAILURE = 9, // used only by ARM EABI
+        }
+
+        pub enum _Unwind_Context {}
+
+        pub type _Unwind_Trace_Fn =
+                extern fn(ctx: *_Unwind_Context,
+                          arg: *libc::c_void) -> _Unwind_Reason_Code;
+
+        extern {
+            pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
+                                     trace_argument: *libc::c_void)
+                        -> _Unwind_Reason_Code;
+
+            #[cfg(not(target_os = "android"),
+                  not(target_os = "linux", target_arch = "arm"))]
+            pub fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t;
+            #[cfg(not(target_os = "android"),
+                  not(target_os = "linux", target_arch = "arm"))]
+            pub fn _Unwind_FindEnclosingFunction(pc: *libc::c_void)
+                -> *libc::c_void;
+        }
+
+        // On android, the function _Unwind_GetIP is a macro, and this is the
+        // expansion of the macro. This is all copy/pasted directly from the
+        // header file with the definition of _Unwind_GetIP.
+        #[cfg(target_os = "android")]
+        #[cfg(target_os = "linux", target_arch = "arm")]
+        pub unsafe fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t {
+            #[repr(C)]
+            enum _Unwind_VRS_Result {
+                _UVRSR_OK = 0,
+                _UVRSR_NOT_IMPLEMENTED = 1,
+                _UVRSR_FAILED = 2,
+            }
+            #[repr(C)]
+            enum _Unwind_VRS_RegClass {
+                _UVRSC_CORE = 0,
+                _UVRSC_VFP = 1,
+                _UVRSC_FPA = 2,
+                _UVRSC_WMMXD = 3,
+                _UVRSC_WMMXC = 4,
+            }
+            #[repr(C)]
+            enum _Unwind_VRS_DataRepresentation {
+                _UVRSD_UINT32 = 0,
+                _UVRSD_VFPX = 1,
+                _UVRSD_FPAX = 2,
+                _UVRSD_UINT64 = 3,
+                _UVRSD_FLOAT = 4,
+                _UVRSD_DOUBLE = 5,
+            }
+
+            type _Unwind_Word = libc::c_uint;
+            extern {
+                fn _Unwind_VRS_Get(ctx: *_Unwind_Context,
+                                   klass: _Unwind_VRS_RegClass,
+                                   word: _Unwind_Word,
+                                   repr: _Unwind_VRS_DataRepresentation,
+                                   data: *mut libc::c_void)
+                    -> _Unwind_VRS_Result;
+            }
+
+            let mut val: _Unwind_Word = 0;
+            let ptr = &mut val as *mut _Unwind_Word;
+            let _ = _Unwind_VRS_Get(ctx, _UVRSC_CORE, 15, _UVRSD_UINT32,
+                                    ptr as *mut libc::c_void);
+            (val & !1) as libc::uintptr_t
+        }
+
+        // This function also doesn't exist on android or arm/linux, so make it
+        // a no-op
+        #[cfg(target_os = "android")]
+        #[cfg(target_os = "linux", target_arch = "arm")]
+        pub unsafe fn _Unwind_FindEnclosingFunction(pc: *libc::c_void)
+            -> *libc::c_void
+        {
+            pc
+        }
+    }
 }
 
 /// As always, windows has something very different than unix, we mainly want
diff --git a/src/libstd/rt/bookkeeping.rs b/src/libstd/rt/bookkeeping.rs
deleted file mode 100644
index 9e772d8ad23..00000000000
--- a/src/libstd/rt/bookkeeping.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2013-2014 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.
-
-//! Task bookkeeping
-//!
-//! This module keeps track of the number of running tasks so that entry points
-//! with libnative know when it's possible to exit the program (once all tasks
-//! have exited).
-//!
-//! The green counterpart for this is bookkeeping on sched pools, and it's up to
-//! each respective runtime to make sure that they call increment() and
-//! decrement() manually.
-
-#![experimental] // this is a massive code smell
-#![doc(hidden)]
-
-use sync::atomics;
-use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-
-static mut TASK_COUNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
-static mut TASK_LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-
-pub fn increment() {
-    let _ = unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst) };
-}
-
-pub fn decrement() {
-    unsafe {
-        if TASK_COUNT.fetch_sub(1, atomics::SeqCst) == 1 {
-            let guard = TASK_LOCK.lock();
-            guard.signal();
-        }
-    }
-}
-
-/// Waits for all other native tasks in the system to exit. This is only used by
-/// the entry points of native programs
-pub fn wait_for_other_tasks() {
-    unsafe {
-        let guard = TASK_LOCK.lock();
-        while TASK_COUNT.load(atomics::SeqCst) > 0 {
-            guard.wait();
-        }
-    }
-}
diff --git a/src/libstd/rt/env.rs b/src/libstd/rt/env.rs
deleted file mode 100644
index 7271464d1e9..00000000000
--- a/src/libstd/rt/env.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013 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.
-
-//! Runtime environment settings
-
-use from_str::from_str;
-use option::{Some, None};
-use os;
-use str::Str;
-
-// Note that these are all accessed without any synchronization.
-// They are expected to be initialized once then left alone.
-
-static mut MIN_STACK: uint = 2 * 1024 * 1024;
-/// This default corresponds to 20M of cache per scheduler (at the default size).
-static mut MAX_CACHED_STACKS: uint = 10;
-static mut DEBUG_BORROW: bool = false;
-
-pub fn init() {
-    unsafe {
-        match os::getenv("RUST_MIN_STACK") {
-            Some(s) => match from_str(s.as_slice()) {
-                Some(i) => MIN_STACK = i,
-                None => ()
-            },
-            None => ()
-        }
-        match os::getenv("RUST_MAX_CACHED_STACKS") {
-            Some(max) => {
-                MAX_CACHED_STACKS =
-                    from_str(max.as_slice()).expect("expected positive \
-                                                     integer in \
-                                                     RUST_MAX_CACHED_STACKS")
-            }
-            None => ()
-        }
-        match os::getenv("RUST_DEBUG_BORROW") {
-            Some(_) => DEBUG_BORROW = true,
-            None => ()
-        }
-    }
-}
-
-pub fn min_stack() -> uint {
-    unsafe { MIN_STACK }
-}
-
-pub fn max_cached_stacks() -> uint {
-    unsafe { MAX_CACHED_STACKS }
-}
-
-pub fn debug_borrow() -> bool {
-    unsafe { DEBUG_BORROW }
-}
diff --git a/src/libstd/rt/libunwind.rs b/src/libstd/rt/libunwind.rs
deleted file mode 100644
index 00301e71b0d..00000000000
--- a/src/libstd/rt/libunwind.rs
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2014 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.
-
-//! Unwind library interface
-
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case_functions)]
-#![allow(dead_code)] // these are just bindings
-
-use libc;
-
-#[cfg(not(target_arch = "arm"))]
-#[repr(C)]
-pub enum _Unwind_Action {
-    _UA_SEARCH_PHASE = 1,
-    _UA_CLEANUP_PHASE = 2,
-    _UA_HANDLER_FRAME = 4,
-    _UA_FORCE_UNWIND = 8,
-    _UA_END_OF_STACK = 16,
-}
-
-#[cfg(target_arch = "arm")]
-#[repr(C)]
-pub enum _Unwind_State {
-    _US_VIRTUAL_UNWIND_FRAME = 0,
-    _US_UNWIND_FRAME_STARTING = 1,
-    _US_UNWIND_FRAME_RESUME = 2,
-    _US_ACTION_MASK = 3,
-    _US_FORCE_UNWIND = 8,
-    _US_END_OF_STACK = 16
-}
-
-#[repr(C)]
-pub enum _Unwind_Reason_Code {
-    _URC_NO_REASON = 0,
-    _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
-    _URC_FATAL_PHASE2_ERROR = 2,
-    _URC_FATAL_PHASE1_ERROR = 3,
-    _URC_NORMAL_STOP = 4,
-    _URC_END_OF_STACK = 5,
-    _URC_HANDLER_FOUND = 6,
-    _URC_INSTALL_CONTEXT = 7,
-    _URC_CONTINUE_UNWIND = 8,
-    _URC_FAILURE = 9, // used only by ARM EABI
-}
-
-pub type _Unwind_Exception_Class = u64;
-
-pub type _Unwind_Word = libc::uintptr_t;
-
-#[cfg(target_arch = "x86")]
-pub static unwinder_private_data_size: int = 5;
-
-#[cfg(target_arch = "x86_64")]
-pub static unwinder_private_data_size: int = 2;
-
-#[cfg(target_arch = "arm")]
-pub static unwinder_private_data_size: int = 20;
-
-#[cfg(target_arch = "mips")]
-pub static unwinder_private_data_size: int = 2;
-
-pub struct _Unwind_Exception {
-    pub exception_class: _Unwind_Exception_Class,
-    pub exception_cleanup: _Unwind_Exception_Cleanup_Fn,
-    pub private: [_Unwind_Word, ..unwinder_private_data_size],
-}
-
-pub enum _Unwind_Context {}
-
-pub type _Unwind_Exception_Cleanup_Fn =
-        extern "C" fn(unwind_code: _Unwind_Reason_Code,
-                      exception: *_Unwind_Exception);
-
-pub type _Unwind_Trace_Fn =
-        extern "C" fn(ctx: *_Unwind_Context,
-                      arg: *libc::c_void) -> _Unwind_Reason_Code;
-
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "freebsd")]
-#[cfg(target_os = "win32")]
-#[link(name = "gcc_s")]
-extern {}
-
-#[cfg(target_os = "android")]
-#[link(name = "gcc")]
-extern {}
-
-extern "C" {
-    pub fn _Unwind_RaiseException(exception: *_Unwind_Exception)
-                -> _Unwind_Reason_Code;
-    pub fn _Unwind_DeleteException(exception: *_Unwind_Exception);
-    pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
-                             trace_argument: *libc::c_void)
-                -> _Unwind_Reason_Code;
-
-    #[cfg(not(target_os = "android"),
-          not(target_os = "linux", target_arch = "arm"))]
-    pub fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t;
-    #[cfg(not(target_os = "android"),
-          not(target_os = "linux", target_arch = "arm"))]
-    pub fn _Unwind_FindEnclosingFunction(pc: *libc::c_void) -> *libc::c_void;
-}
-
-// On android, the function _Unwind_GetIP is a macro, and this is the expansion
-// of the macro. This is all copy/pasted directly from the header file with the
-// definition of _Unwind_GetIP.
-#[cfg(target_os = "android")]
-#[cfg(target_os = "linux", target_arch = "arm")]
-pub unsafe fn _Unwind_GetIP(ctx: *_Unwind_Context) -> libc::uintptr_t {
-    #[repr(C)]
-    enum _Unwind_VRS_Result {
-        _UVRSR_OK = 0,
-        _UVRSR_NOT_IMPLEMENTED = 1,
-        _UVRSR_FAILED = 2,
-    }
-    #[repr(C)]
-    enum _Unwind_VRS_RegClass {
-        _UVRSC_CORE = 0,
-        _UVRSC_VFP = 1,
-        _UVRSC_FPA = 2,
-        _UVRSC_WMMXD = 3,
-        _UVRSC_WMMXC = 4,
-    }
-    #[repr(C)]
-    enum _Unwind_VRS_DataRepresentation {
-        _UVRSD_UINT32 = 0,
-        _UVRSD_VFPX = 1,
-        _UVRSD_FPAX = 2,
-        _UVRSD_UINT64 = 3,
-        _UVRSD_FLOAT = 4,
-        _UVRSD_DOUBLE = 5,
-    }
-
-    type _Unwind_Word = libc::c_uint;
-    extern {
-        fn _Unwind_VRS_Get(ctx: *_Unwind_Context,
-                           klass: _Unwind_VRS_RegClass,
-                           word: _Unwind_Word,
-                           repr: _Unwind_VRS_DataRepresentation,
-                           data: *mut libc::c_void) -> _Unwind_VRS_Result;
-    }
-
-    let mut val: _Unwind_Word = 0;
-    let ptr = &mut val as *mut _Unwind_Word;
-    let _ = _Unwind_VRS_Get(ctx, _UVRSC_CORE, 15, _UVRSD_UINT32,
-                            ptr as *mut libc::c_void);
-    (val & !1) as libc::uintptr_t
-}
-
-// This function also doesn't exist on android or arm/linux, so make it a no-op
-#[cfg(target_os = "android")]
-#[cfg(target_os = "linux", target_arch = "arm")]
-pub unsafe fn _Unwind_FindEnclosingFunction(pc: *libc::c_void) -> *libc::c_void {
-    pc
-}
diff --git a/src/libstd/rt/local.rs b/src/libstd/rt/local.rs
deleted file mode 100644
index 9f0ed804480..00000000000
--- a/src/libstd/rt/local.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2013 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 option::Option;
-use owned::Box;
-use rt::task::Task;
-use rt::local_ptr;
-
-/// Encapsulates some task-local data.
-pub trait Local<Borrowed> {
-    fn put(value: Box<Self>);
-    fn take() -> Box<Self>;
-    fn try_take() -> Option<Box<Self>>;
-    fn exists(unused_value: Option<Self>) -> bool;
-    fn borrow(unused_value: Option<Self>) -> Borrowed;
-    unsafe fn unsafe_take() -> Box<Self>;
-    unsafe fn unsafe_borrow() -> *mut Self;
-    unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
-}
-
-#[allow(visible_private_types)]
-impl Local<local_ptr::Borrowed<Task>> for Task {
-    #[inline]
-    fn put(value: Box<Task>) { unsafe { local_ptr::put(value) } }
-    #[inline]
-    fn take() -> Box<Task> { unsafe { local_ptr::take() } }
-    #[inline]
-    fn try_take() -> Option<Box<Task>> { unsafe { local_ptr::try_take() } }
-    fn exists(_: Option<Task>) -> bool { local_ptr::exists() }
-    #[inline]
-    fn borrow(_: Option<Task>) -> local_ptr::Borrowed<Task> {
-        unsafe {
-            local_ptr::borrow::<Task>()
-        }
-    }
-    #[inline]
-    unsafe fn unsafe_take() -> Box<Task> { local_ptr::unsafe_take() }
-    #[inline]
-    unsafe fn unsafe_borrow() -> *mut Task { local_ptr::unsafe_borrow() }
-    #[inline]
-    unsafe fn try_unsafe_borrow() -> Option<*mut Task> {
-        local_ptr::try_unsafe_borrow()
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use option::{None, Option};
-    use rt::thread::Thread;
-    use super::*;
-    use owned::Box;
-    use rt::task::Task;
-
-    #[test]
-    fn thread_local_task_smoke_test() {
-        Thread::start(proc() {
-            let task = box Task::new();
-            Local::put(task);
-            let task: Box<Task> = Local::take();
-            cleanup_task(task);
-        }).join();
-    }
-
-    #[test]
-    fn thread_local_task_two_instances() {
-        Thread::start(proc() {
-            let task = box Task::new();
-            Local::put(task);
-            let task: Box<Task> = Local::take();
-            cleanup_task(task);
-            let task = box Task::new();
-            Local::put(task);
-            let task: Box<Task> = Local::take();
-            cleanup_task(task);
-        }).join();
-    }
-
-    #[test]
-    fn borrow_smoke_test() {
-        Thread::start(proc() {
-            let task = box Task::new();
-            Local::put(task);
-
-            unsafe {
-                let _task: *mut Task = Local::unsafe_borrow();
-            }
-            let task: Box<Task> = Local::take();
-            cleanup_task(task);
-        }).join();
-    }
-
-    #[test]
-    fn borrow_with_return() {
-        Thread::start(proc() {
-            let task = box Task::new();
-            Local::put(task);
-
-            {
-                let _ = Local::borrow(None::<Task>);
-            }
-
-            let task: Box<Task> = Local::take();
-            cleanup_task(task);
-        }).join();
-    }
-
-    #[test]
-    fn try_take() {
-        Thread::start(proc() {
-            let task = box Task::new();
-            Local::put(task);
-
-            let t: Box<Task> = Local::try_take().unwrap();
-            let u: Option<Box<Task>> = Local::try_take();
-            assert!(u.is_none());
-
-            cleanup_task(t);
-        }).join();
-    }
-
-    fn cleanup_task(mut t: Box<Task>) {
-        t.destroyed = true;
-    }
-
-}
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
deleted file mode 100644
index 240d137adc6..00000000000
--- a/src/libstd/rt/local_heap.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2013 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.
-
-//! The local, garbage collected heap
-
-use alloc::util;
-use iter::Iterator;
-use libc::{c_void, free};
-use mem;
-use ops::Drop;
-use option::{Option, None, Some};
-use ptr::RawPtr;
-use ptr;
-use raw;
-use rt::libc_heap;
-use rt::local::Local;
-use rt::task::Task;
-use slice::{ImmutableVector, Vector};
-use vec::Vec;
-
-// This has no meaning with out rtdebug also turned on.
-#[cfg(rtdebug)]
-static TRACK_ALLOCATIONS: int = 0;
-#[cfg(rtdebug)]
-static MAGIC: u32 = 0xbadc0ffe;
-
-pub type Box = raw::Box<()>;
-
-pub struct MemoryRegion {
-    allocations: Vec<*AllocHeader>,
-    live_allocations: uint,
-}
-
-pub struct LocalHeap {
-    memory_region: MemoryRegion,
-
-    live_allocs: *mut raw::Box<()>,
-}
-
-impl LocalHeap {
-    #[inline]
-    pub fn new() -> LocalHeap {
-        let region = MemoryRegion {
-            allocations: Vec::new(),
-            live_allocations: 0,
-        };
-        LocalHeap {
-            memory_region: region,
-            live_allocs: ptr::mut_null(),
-        }
-    }
-
-    #[inline]
-    pub fn alloc(&mut self, drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut Box {
-        let total_size = util::get_box_size(size, align);
-        let alloc = self.memory_region.malloc(total_size);
-        {
-            // Make sure that we can't use `mybox` outside of this scope
-            let mybox: &mut Box = unsafe { mem::transmute(alloc) };
-            // Clear out this box, and move it to the front of the live
-            // allocations list
-            mybox.drop_glue = drop_glue;
-            mybox.ref_count = 1;
-            mybox.prev = ptr::mut_null();
-            mybox.next = self.live_allocs;
-            if !self.live_allocs.is_null() {
-                unsafe { (*self.live_allocs).prev = alloc; }
-            }
-            self.live_allocs = alloc;
-        }
-        return alloc;
-    }
-
-    #[inline]
-    pub fn realloc(&mut self, ptr: *mut Box, size: uint) -> *mut Box {
-        // Make sure that we can't use `mybox` outside of this scope
-        let total_size = size + mem::size_of::<Box>();
-        let new_box = self.memory_region.realloc(ptr, total_size);
-        {
-            // Fix links because we could have moved around
-            let mybox: &mut Box = unsafe { mem::transmute(new_box) };
-            if !mybox.prev.is_null() {
-                unsafe { (*mybox.prev).next = new_box; }
-            }
-            if !mybox.next.is_null() {
-                unsafe { (*mybox.next).prev = new_box; }
-            }
-        }
-        if self.live_allocs == ptr {
-            self.live_allocs = new_box;
-        }
-        return new_box;
-    }
-
-    #[inline]
-    pub fn free(&mut self, alloc: *mut Box) {
-        {
-            // Make sure that we can't use `mybox` outside of this scope
-            let mybox: &mut Box = unsafe { mem::transmute(alloc) };
-
-            // Unlink it from the linked list
-            if !mybox.prev.is_null() {
-                unsafe { (*mybox.prev).next = mybox.next; }
-            }
-            if !mybox.next.is_null() {
-                unsafe { (*mybox.next).prev = mybox.prev; }
-            }
-            if self.live_allocs == alloc {
-                self.live_allocs = mybox.next;
-            }
-        }
-
-        self.memory_region.free(alloc);
-    }
-}
-
-impl Drop for LocalHeap {
-    fn drop(&mut self) {
-        assert!(self.live_allocs.is_null());
-    }
-}
-
-#[cfg(rtdebug)]
-struct AllocHeader {
-    magic: u32,
-    index: i32,
-    size: u32,
-}
-#[cfg(not(rtdebug))]
-struct AllocHeader;
-
-impl AllocHeader {
-    #[cfg(rtdebug)]
-    fn init(&mut self, size: u32) {
-        if TRACK_ALLOCATIONS > 0 {
-            self.magic = MAGIC;
-            self.index = -1;
-            self.size = size;
-        }
-    }
-    #[cfg(not(rtdebug))]
-    fn init(&mut self, _size: u32) {}
-
-    #[cfg(rtdebug)]
-    fn assert_sane(&self) {
-        if TRACK_ALLOCATIONS > 0 {
-            rtassert!(self.magic == MAGIC);
-        }
-    }
-    #[cfg(not(rtdebug))]
-    fn assert_sane(&self) {}
-
-    #[cfg(rtdebug)]
-    fn update_size(&mut self, size: u32) {
-        if TRACK_ALLOCATIONS > 0 {
-            self.size = size;
-        }
-    }
-    #[cfg(not(rtdebug))]
-    fn update_size(&mut self, _size: u32) {}
-
-    fn as_box(&mut self) -> *mut Box {
-        let myaddr: uint = unsafe { mem::transmute(self) };
-        (myaddr + AllocHeader::size()) as *mut Box
-    }
-
-    fn size() -> uint {
-        // For some platforms, 16 byte alignment is required.
-        let ptr_size = 16;
-        let header_size = mem::size_of::<AllocHeader>();
-        return (header_size + ptr_size - 1) / ptr_size * ptr_size;
-    }
-
-    fn from(a_box: *mut Box) -> *mut AllocHeader {
-        (a_box as uint - AllocHeader::size()) as *mut AllocHeader
-    }
-}
-
-impl MemoryRegion {
-    #[inline]
-    fn malloc(&mut self, size: uint) -> *mut Box {
-        let total_size = size + AllocHeader::size();
-        let alloc: *AllocHeader = unsafe {
-            libc_heap::malloc_raw(total_size) as *AllocHeader
-        };
-
-        let alloc: &mut AllocHeader = unsafe { mem::transmute(alloc) };
-        alloc.init(size as u32);
-        self.claim(alloc);
-        self.live_allocations += 1;
-
-        return alloc.as_box();
-    }
-
-    #[inline]
-    fn realloc(&mut self, alloc: *mut Box, size: uint) -> *mut Box {
-        rtassert!(!alloc.is_null());
-        let orig_alloc = AllocHeader::from(alloc);
-        unsafe { (*orig_alloc).assert_sane(); }
-
-        let total_size = size + AllocHeader::size();
-        let alloc: *AllocHeader = unsafe {
-            libc_heap::realloc_raw(orig_alloc as *mut u8, total_size) as *AllocHeader
-        };
-
-        let alloc: &mut AllocHeader = unsafe { mem::transmute(alloc) };
-        alloc.assert_sane();
-        alloc.update_size(size as u32);
-        self.update(alloc, orig_alloc as *AllocHeader);
-        return alloc.as_box();
-    }
-
-    #[inline]
-    fn free(&mut self, alloc: *mut Box) {
-        rtassert!(!alloc.is_null());
-        let alloc = AllocHeader::from(alloc);
-        unsafe {
-            (*alloc).assert_sane();
-            self.release(mem::transmute(alloc));
-            rtassert!(self.live_allocations > 0);
-            self.live_allocations -= 1;
-            free(alloc as *mut c_void)
-        }
-    }
-
-    #[cfg(rtdebug)]
-    fn claim(&mut self, alloc: &mut AllocHeader) {
-        alloc.assert_sane();
-        if TRACK_ALLOCATIONS > 1 {
-            alloc.index = self.allocations.len() as i32;
-            self.allocations.push(&*alloc as *AllocHeader);
-        }
-    }
-    #[cfg(not(rtdebug))]
-    #[inline]
-    fn claim(&mut self, _alloc: &mut AllocHeader) {}
-
-    #[cfg(rtdebug)]
-    fn release(&mut self, alloc: &AllocHeader) {
-        alloc.assert_sane();
-        if TRACK_ALLOCATIONS > 1 {
-            rtassert!(self.allocations.as_slice()[alloc.index] == alloc as *AllocHeader);
-            self.allocations.as_mut_slice()[alloc.index] = ptr::null();
-        }
-    }
-    #[cfg(not(rtdebug))]
-    #[inline]
-    fn release(&mut self, _alloc: &AllocHeader) {}
-
-    #[cfg(rtdebug)]
-    fn update(&mut self, alloc: &mut AllocHeader, orig: *AllocHeader) {
-        alloc.assert_sane();
-        if TRACK_ALLOCATIONS > 1 {
-            rtassert!(self.allocations.as_slice()[alloc.index] == orig);
-            self.allocations.as_mut_slice()[alloc.index] = &*alloc as *AllocHeader;
-        }
-    }
-    #[cfg(not(rtdebug))]
-    #[inline]
-    fn update(&mut self, _alloc: &mut AllocHeader, _orig: *AllocHeader) {}
-}
-
-impl Drop for MemoryRegion {
-    fn drop(&mut self) {
-        if self.live_allocations != 0 {
-            rtabort!("leaked managed memory ({} objects)", self.live_allocations);
-        }
-        rtassert!(self.allocations.as_slice().iter().all(|s| s.is_null()));
-    }
-}
-
-
-#[cfg(not(test))]
-#[lang="malloc"]
-#[inline]
-pub unsafe fn local_malloc_(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
-    local_malloc(drop_glue, size, align)
-}
-
-#[inline]
-pub unsafe fn local_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *u8 {
-    // FIXME: Unsafe borrow for speed. Lame.
-    let task: Option<*mut Task> = Local::try_unsafe_borrow();
-    match task {
-        Some(task) => {
-            (*task).heap.alloc(drop_glue, size, align) as *u8
-        }
-        None => rtabort!("local malloc outside of task")
-    }
-}
-
-#[cfg(not(test))]
-#[lang="free"]
-#[inline]
-pub unsafe fn local_free_(ptr: *u8) {
-    local_free(ptr)
-}
-
-// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
-// inside a landing pad may corrupt the state of the exception handler. If a
-// problem occurs, call exit instead.
-#[inline]
-pub unsafe fn local_free(ptr: *u8) {
-    // FIXME: Unsafe borrow for speed. Lame.
-    let task_ptr: Option<*mut Task> = Local::try_unsafe_borrow();
-    match task_ptr {
-        Some(task) => {
-            (*task).heap.free(ptr as *mut Box)
-        }
-        None => rtabort!("local free outside of task")
-    }
-}
-
-pub fn live_allocs() -> *mut Box {
-    Local::borrow(None::<Task>).heap.live_allocs
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-
-    #[bench]
-    fn alloc_managed_small(b: &mut Bencher) {
-        b.iter(|| { @10; });
-    }
-
-    #[bench]
-    fn alloc_managed_big(b: &mut Bencher) {
-        b.iter(|| { @([10, ..1000]); });
-    }
-}
diff --git a/src/libstd/rt/local_ptr.rs b/src/libstd/rt/local_ptr.rs
deleted file mode 100644
index 1197a4ccbe6..00000000000
--- a/src/libstd/rt/local_ptr.rs
+++ /dev/null
@@ -1,404 +0,0 @@
-// Copyright 2013 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.
-
-//! Access to a single thread-local pointer.
-//!
-//! The runtime will use this for storing Box<Task>.
-//!
-//! FIXME: Add runtime checks for usage of inconsistent pointer types.
-//! and for overwriting an existing pointer.
-
-#![allow(dead_code)]
-
-use mem;
-use ops::{Drop, Deref, DerefMut};
-use owned::Box;
-use ptr::RawPtr;
-
-#[cfg(windows)]               // mingw-w32 doesn't like thread_local things
-#[cfg(target_os = "android")] // see #10686
-pub use self::native::{init, cleanup, put, take, try_take, unsafe_take, exists,
-                       unsafe_borrow, try_unsafe_borrow};
-
-#[cfg(not(windows), not(target_os = "android"))]
-pub use self::compiled::{init, cleanup, put, take, try_take, unsafe_take, exists,
-                         unsafe_borrow, try_unsafe_borrow};
-
-/// Encapsulates a borrowed value. When this value goes out of scope, the
-/// pointer is returned.
-pub struct Borrowed<T> {
-    val: *(),
-}
-
-#[unsafe_destructor]
-impl<T> Drop for Borrowed<T> {
-    fn drop(&mut self) {
-        unsafe {
-            if self.val.is_null() {
-                rtabort!("Aiee, returning null borrowed object!");
-            }
-            let val: Box<T> = mem::transmute(self.val);
-            put::<T>(val);
-            rtassert!(exists());
-        }
-    }
-}
-
-impl<T> Deref<T> for Borrowed<T> {
-    fn deref<'a>(&'a self) -> &'a T {
-        unsafe { &*(self.val as *T) }
-    }
-}
-
-impl<T> DerefMut<T> for Borrowed<T> {
-    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
-        unsafe { &mut *(self.val as *mut T) }
-    }
-}
-
-/// Borrow the thread-local value from thread-local storage.
-/// While the value is borrowed it is not available in TLS.
-///
-/// # Safety note
-///
-/// Does not validate the pointer type.
-#[inline]
-pub unsafe fn borrow<T>() -> Borrowed<T> {
-    let val: *() = mem::transmute(take::<T>());
-    Borrowed {
-        val: val,
-    }
-}
-
-/// Compiled implementation of accessing the runtime local pointer. This is
-/// implemented using LLVM's thread_local attribute which isn't necessarily
-/// working on all platforms. This implementation is faster, however, so we use
-/// it wherever possible.
-#[cfg(not(windows), not(target_os = "android"))]
-pub mod compiled {
-    use mem;
-    use option::{Option, Some, None};
-    use owned::Box;
-    use ptr::RawPtr;
-
-    #[cfg(test)]
-    pub use realstd::rt::shouldnt_be_public::RT_TLS_PTR;
-
-    #[cfg(not(test))]
-    #[thread_local]
-    pub static mut RT_TLS_PTR: *mut u8 = 0 as *mut u8;
-
-    pub fn init() {}
-
-    pub unsafe fn cleanup() {}
-
-    // Rationale for all of these functions being inline(never)
-    //
-    // The #[thread_local] annotation gets propagated all the way through to
-    // LLVM, meaning the global is specially treated by LLVM to lower it to an
-    // efficient sequence of instructions. This also involves dealing with fun
-    // stuff in object files and whatnot. Regardless, it turns out this causes
-    // trouble with green threads and lots of optimizations turned on. The
-    // following case study was done on linux x86_64, but I would imagine that
-    // other platforms are similar.
-    //
-    // On linux, the instruction sequence for loading the tls pointer global
-    // looks like:
-    //
-    //      mov %fs:0x0, %rax
-    //      mov -0x8(%rax), %rbx
-    //
-    // This code leads me to believe that (%fs:0x0) is a table, and then the
-    // table contains the TLS values for the process. Hence, the slot at offset
-    // -0x8 is the task TLS pointer. This leads us to the conclusion that this
-    // table is the actual thread local part of each thread. The kernel sets up
-    // the fs segment selector to point at the right region of memory for each
-    // thread.
-    //
-    // Optimizations lead me to believe that this code is lowered to these
-    // instructions in the LLVM codegen passes, because you'll see code like
-    // this when everything is optimized:
-    //
-    //      mov %fs:0x0, %r14
-    //      mov -0x8(%r14), %rbx
-    //      // do something with %rbx, the rust Task pointer
-    //
-    //      ... // <- do more things
-    //
-    //      mov -0x8(%r14), %rbx
-    //      // do something else with %rbx
-    //
-    // Note that the optimization done here is that the first load is not
-    // duplicated during the lower instructions. This means that the %fs:0x0
-    // memory location is only dereferenced once.
-    //
-    // Normally, this is actually a good thing! With green threads, however,
-    // it's very possible for the code labeled "do more things" to context
-    // switch to another thread. If this happens, then we *must* re-load %fs:0x0
-    // because it's changed (we're on a different thread). If we don't re-load
-    // the table location, then we'll be reading the original thread's TLS
-    // values, not our thread's TLS values.
-    //
-    // Hence, we never inline these functions. By never inlining, we're
-    // guaranteed that loading the table is a local decision which is forced to
-    // *always* happen.
-
-    /// Give a pointer to thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    #[inline(never)] // see comments above
-    pub unsafe fn put<T>(sched: Box<T>) {
-        RT_TLS_PTR = mem::transmute(sched)
-    }
-
-    /// Take ownership of a pointer from thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    #[inline(never)] // see comments above
-    pub unsafe fn take<T>() -> Box<T> {
-        let ptr = RT_TLS_PTR;
-        rtassert!(!ptr.is_null());
-        let ptr: Box<T> = mem::transmute(ptr);
-        // can't use `as`, due to type not matching with `cfg(test)`
-        RT_TLS_PTR = mem::transmute(0);
-        ptr
-    }
-
-    /// Optionally take ownership of a pointer from thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    #[inline(never)] // see comments above
-    pub unsafe fn try_take<T>() -> Option<Box<T>> {
-        let ptr = RT_TLS_PTR;
-        if ptr.is_null() {
-            None
-        } else {
-            let ptr: Box<T> = mem::transmute(ptr);
-            // can't use `as`, due to type not matching with `cfg(test)`
-            RT_TLS_PTR = mem::transmute(0);
-            Some(ptr)
-        }
-    }
-
-    /// Take ownership of a pointer from thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    /// Leaves the old pointer in TLS for speed.
-    #[inline(never)] // see comments above
-    pub unsafe fn unsafe_take<T>() -> Box<T> {
-        mem::transmute(RT_TLS_PTR)
-    }
-
-    /// Check whether there is a thread-local pointer installed.
-    #[inline(never)] // see comments above
-    pub fn exists() -> bool {
-        unsafe {
-            RT_TLS_PTR.is_not_null()
-        }
-    }
-
-    #[inline(never)] // see comments above
-    pub unsafe fn unsafe_borrow<T>() -> *mut T {
-        if RT_TLS_PTR.is_null() {
-            rtabort!("thread-local pointer is null. bogus!");
-        }
-        RT_TLS_PTR as *mut T
-    }
-
-    #[inline(never)] // see comments above
-    pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
-        if RT_TLS_PTR.is_null() {
-            None
-        } else {
-            Some(RT_TLS_PTR as *mut T)
-        }
-    }
-}
-
-/// Native implementation of having the runtime thread-local pointer. This
-/// implementation uses the `thread_local_storage` module to provide a
-/// thread-local value.
-pub mod native {
-    use mem;
-    use option::{Option, Some, None};
-    use owned::Box;
-    use ptr::RawPtr;
-    use ptr;
-    use tls = rt::thread_local_storage;
-
-    static mut RT_TLS_KEY: tls::Key = -1;
-
-    /// Initialize the TLS key. Other ops will fail if this isn't executed
-    /// first.
-    pub fn init() {
-        unsafe {
-            tls::create(&mut RT_TLS_KEY);
-        }
-    }
-
-    pub unsafe fn cleanup() {
-        rtassert!(RT_TLS_KEY != -1);
-        tls::destroy(RT_TLS_KEY);
-    }
-
-    /// Give a pointer to thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    #[inline]
-    pub unsafe fn put<T>(sched: Box<T>) {
-        let key = tls_key();
-        let void_ptr: *mut u8 = mem::transmute(sched);
-        tls::set(key, void_ptr);
-    }
-
-    /// Take ownership of a pointer from thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    #[inline]
-    pub unsafe fn take<T>() -> Box<T> {
-        let key = tls_key();
-        let void_ptr: *mut u8 = tls::get(key);
-        if void_ptr.is_null() {
-            rtabort!("thread-local pointer is null. bogus!");
-        }
-        let ptr: Box<T> = mem::transmute(void_ptr);
-        tls::set(key, ptr::mut_null());
-        return ptr;
-    }
-
-    /// Optionally take ownership of a pointer from thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    #[inline]
-    pub unsafe fn try_take<T>() -> Option<Box<T>> {
-        match maybe_tls_key() {
-            Some(key) => {
-                let void_ptr: *mut u8 = tls::get(key);
-                if void_ptr.is_null() {
-                    None
-                } else {
-                    let ptr: Box<T> = mem::transmute(void_ptr);
-                    tls::set(key, ptr::mut_null());
-                    Some(ptr)
-                }
-            }
-            None => None
-        }
-    }
-
-    /// Take ownership of a pointer from thread-local storage.
-    ///
-    /// # Safety note
-    ///
-    /// Does not validate the pointer type.
-    /// Leaves the old pointer in TLS for speed.
-    #[inline]
-    pub unsafe fn unsafe_take<T>() -> Box<T> {
-        let key = tls_key();
-        let void_ptr: *mut u8 = tls::get(key);
-        if void_ptr.is_null() {
-            rtabort!("thread-local pointer is null. bogus!");
-        }
-        let ptr: Box<T> = mem::transmute(void_ptr);
-        return ptr;
-    }
-
-    /// Check whether there is a thread-local pointer installed.
-    pub fn exists() -> bool {
-        unsafe {
-            match maybe_tls_key() {
-                Some(key) => tls::get(key).is_not_null(),
-                None => false
-            }
-        }
-    }
-
-    /// Borrow a mutable reference to the thread-local value
-    ///
-    /// # Safety Note
-    ///
-    /// Because this leaves the value in thread-local storage it is possible
-    /// For the Scheduler pointer to be aliased
-    pub unsafe fn unsafe_borrow<T>() -> *mut T {
-        let key = tls_key();
-        let void_ptr = tls::get(key);
-        if void_ptr.is_null() {
-            rtabort!("thread-local pointer is null. bogus!");
-        }
-        void_ptr as *mut T
-    }
-
-    pub unsafe fn try_unsafe_borrow<T>() -> Option<*mut T> {
-        match maybe_tls_key() {
-            Some(key) => {
-                let void_ptr = tls::get(key);
-                if void_ptr.is_null() {
-                    None
-                } else {
-                    Some(void_ptr as *mut T)
-                }
-            }
-            None => None
-        }
-    }
-
-    #[inline]
-    fn tls_key() -> tls::Key {
-        match maybe_tls_key() {
-            Some(key) => key,
-            None => rtabort!("runtime tls key not initialized")
-        }
-    }
-
-    #[inline]
-    #[cfg(not(test))]
-    #[allow(visible_private_types)]
-    pub fn maybe_tls_key() -> Option<tls::Key> {
-        unsafe {
-            // NB: This is a little racy because, while the key is
-            // initialized under a mutex and it's assumed to be initialized
-            // in the Scheduler ctor by any thread that needs to use it,
-            // we are not accessing the key under a mutex.  Threads that
-            // are not using the new Scheduler but still *want to check*
-            // whether they are running under a new Scheduler may see a 0
-            // value here that is in the process of being initialized in
-            // another thread. I think this is fine since the only action
-            // they could take if it was initialized would be to check the
-            // thread-local value and see that it's not set.
-            if RT_TLS_KEY != -1 {
-                return Some(RT_TLS_KEY);
-            } else {
-                return None;
-            }
-        }
-    }
-
-    #[inline] #[cfg(test)]
-    pub fn maybe_tls_key() -> Option<tls::Key> {
-        use realstd;
-        unsafe {
-            mem::transmute(realstd::rt::shouldnt_be_public::maybe_tls_key())
-        }
-    }
-}
diff --git a/src/libstd/rt/macros.rs b/src/libstd/rt/macros.rs
deleted file mode 100644
index aef41de925f..00000000000
--- a/src/libstd/rt/macros.rs
+++ /dev/null
@@ -1,49 +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.
-
-//! Macros used by the runtime.
-//!
-//! These macros call functions which are only accessible in the `rt` module, so
-//! they aren't defined anywhere outside of the `rt` module.
-
-#![macro_escape]
-
-macro_rules! rterrln (
-    ($($arg:tt)*) => ( {
-        format_args!(::rt::util::dumb_println, $($arg)*)
-    } )
-)
-
-// Some basic logging. Enabled by passing `--cfg rtdebug` to the libstd build.
-macro_rules! rtdebug (
-    ($($arg:tt)*) => ( {
-        if cfg!(rtdebug) {
-            rterrln!($($arg)*)
-        }
-    })
-)
-
-macro_rules! rtassert (
-    ( $arg:expr ) => ( {
-        if ::rt::util::ENFORCE_SANITY {
-            if !$arg {
-                rtabort!(" assertion failed: {}", stringify!($arg));
-            }
-        }
-    } )
-)
-
-
-macro_rules! rtabort (
-    ($($arg:tt)*) => ( {
-        use str::Str;
-        ::rt::util::abort(format!($($arg)*).as_slice());
-    } )
-)
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index d2131ad44fb..e8df7465a74 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -54,159 +54,36 @@ Several modules in `core` are clients of `rt`:
 // FIXME: this should not be here.
 #![allow(missing_doc)]
 
-use any::Any;
-use kinds::Send;
-use option::Option;
-use owned::Box;
-use result::Result;
-use task::TaskOpts;
+use failure;
+use rustrt;
 
-use self::task::{Task, BlockedTask};
-
-// this is somewhat useful when a program wants to spawn a "reasonable" number
-// of workers based on the constraints of the system that it's running on.
-// Perhaps this shouldn't be a `pub use` though and there should be another
-// method...
-pub use self::util::default_sched_threads;
-
-// Export unwinding facilities used by the failure macros
-pub use self::unwind::{begin_unwind, begin_unwind_fmt};
-
-pub use self::util::{Stdio, Stdout, Stderr};
+// TODO: dox
+pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
 
+// TODO: dox
 pub use alloc::{heap, libc_heap};
-
-// Used by I/O tests
-#[experimental]
-pub use self::util::running_on_valgrind;
-
-// FIXME: these probably shouldn't be public...
-#[doc(hidden)]
-pub mod shouldnt_be_public {
-    #[cfg(not(test))]
-    pub use super::local_ptr::native::maybe_tls_key;
-    #[cfg(not(windows), not(target_os = "android"))]
-    pub use super::local_ptr::compiled::RT_TLS_PTR;
-}
-
-// Internal macros used by the runtime.
-mod macros;
-
-/// Implementations of language-critical runtime features like @.
-pub mod task;
-
-// The EventLoop and internal synchronous I/O interface.
-pub mod rtio;
-
-// The Local trait for types that are accessible via thread-local
-// or task-local storage.
-pub mod local;
+pub use rustrt::{task, local, mutex, exclusive, stack, args, rtio};
+pub use rustrt::{Stdio, Stdout, Stderr, begin_unwind, begin_unwind_fmt};
+pub use rustrt::{bookkeeping, at_exit, unwind, DEFAULT_ERROR_CODE, Runtime};
 
 // Bindings to system threading libraries.
 pub mod thread;
 
-// The runtime configuration, read from environment variables.
-pub mod env;
-
-// The local, managed heap
-pub mod local_heap;
-
-// The runtime needs to be able to put a pointer into thread-local storage.
-mod local_ptr;
-
-// Bindings to pthread/windows thread-local storage.
-mod thread_local_storage;
-
-// Stack unwinding
-pub mod unwind;
-
-// The interface to libunwind that rust is using.
-mod libunwind;
-
 // Simple backtrace functionality (to print on failure)
 pub mod backtrace;
 
 // Just stuff
 mod util;
 
-// Global command line argument storage
-pub mod args;
-
-// Support for running procedures when a program has exited.
-mod at_exit_imp;
-
-// Bookkeeping for task counts
-pub mod bookkeeping;
-
-// Stack overflow protection
-pub mod stack;
-
-/// The default error code of the rust runtime if the main task fails instead
-/// of exiting cleanly.
-pub static DEFAULT_ERROR_CODE: int = 101;
-
-/// The interface to the current runtime.
-///
-/// This trait is used as the abstraction between 1:1 and M:N scheduling. The
-/// two independent crates, libnative and libgreen, both have objects which
-/// implement this trait. The goal of this trait is to encompass all the
-/// fundamental differences in functionality between the 1:1 and M:N runtime
-/// modes.
-pub trait Runtime {
-    // Necessary scheduling functions, used for channels and blocking I/O
-    // (sometimes).
-    fn yield_now(~self, cur_task: Box<Task>);
-    fn maybe_yield(~self, cur_task: Box<Task>);
-    fn deschedule(~self, times: uint, cur_task: Box<Task>,
-                  f: |BlockedTask| -> Result<(), BlockedTask>);
-    fn reawaken(~self, to_wake: Box<Task>);
-
-    // Miscellaneous calls which are very different depending on what context
-    // you're in.
-    fn spawn_sibling(~self,
-                     cur_task: Box<Task>,
-                     opts: TaskOpts,
-                     f: proc():Send);
-    fn local_io<'a>(&'a mut self) -> Option<rtio::LocalIo<'a>>;
-    /// The (low, high) edges of the current stack.
-    fn stack_bounds(&self) -> (uint, uint); // (lo, hi)
-    fn can_block(&self) -> bool;
-
-    // FIXME: This is a serious code smell and this should not exist at all.
-    fn wrap(~self) -> Box<Any>;
-}
-
 /// One-time runtime initialization.
 ///
 /// Initializes global state, including frobbing
 /// the crate's logging flags, registering GC
 /// metadata, and storing the process arguments.
+#[allow(experimental)]
 pub fn init(argc: int, argv: **u8) {
-    // FIXME: Derefing these pointers is not safe.
-    // Need to propagate the unsafety to `start`.
-    unsafe {
-        args::init(argc, argv);
-        env::init();
-        local_ptr::init();
-        at_exit_imp::init();
-    }
-}
-
-/// Enqueues a procedure to run when the runtime is cleaned up
-///
-/// The procedure passed to this function will be executed as part of the
-/// runtime cleanup phase. For normal rust programs, this means that it will run
-/// after all other tasks have exited.
-///
-/// The procedure is *not* executed with a local `Task` available to it, so
-/// primitives like logging, I/O, channels, spawning, etc, are *not* available.
-/// This is meant for "bare bones" usage to clean up runtime details, this is
-/// not meant as a general-purpose "let's clean everything up" function.
-///
-/// It is forbidden for procedures to register more `at_exit` handlers when they
-/// are running, and doing so will lead to a process abort.
-pub fn at_exit(f: proc():Send) {
-    at_exit_imp::push(f);
+    rustrt::init(argc, argv);
+    unsafe { unwind::register(failure::on_fail); }
 }
 
 /// One-time runtime cleanup.
@@ -219,8 +96,5 @@ pub fn at_exit(f: proc():Send) {
 /// Invoking cleanup while portions of the runtime are still in use may cause
 /// undefined behavior.
 pub unsafe fn cleanup() {
-    bookkeeping::wait_for_other_tasks();
-    at_exit_imp::run();
-    args::cleanup();
-    local_ptr::cleanup();
+    rustrt::cleanup();
 }
diff --git a/src/libstd/rt/rtio.rs b/src/libstd/rt/rtio.rs
deleted file mode 100644
index 4b5ca6178a7..00000000000
--- a/src/libstd/rt/rtio.rs
+++ /dev/null
@@ -1,361 +0,0 @@
-// Copyright 2013 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.
-
-//! The EventLoop and internal synchronous I/O interface.
-
-use c_str::CString;
-use comm::{Sender, Receiver};
-use kinds::Send;
-use libc::c_int;
-use libc;
-use mem;
-use ops::Drop;
-use option::{Option, Some, None};
-use owned::Box;
-use result::Err;
-use rt::local::Local;
-use rt::task::Task;
-use vec::Vec;
-
-use ai = io::net::addrinfo;
-use io;
-use io::IoResult;
-use io::net::ip::{IpAddr, SocketAddr};
-use io::process::{StdioContainer, ProcessExit};
-use io::signal::Signum;
-use io::{FileMode, FileAccess, FileStat, FilePermission};
-use io::{SeekStyle};
-
-pub trait Callback {
-    fn call(&mut self);
-}
-
-pub trait EventLoop {
-    fn run(&mut self);
-    fn callback(&mut self, arg: proc():Send);
-    fn pausable_idle_callback(&mut self, Box<Callback:Send>)
-                              -> Box<PausableIdleCallback:Send>;
-    fn remote_callback(&mut self, Box<Callback:Send>)
-                       -> Box<RemoteCallback:Send>;
-
-    /// The asynchronous I/O services. Not all event loops may provide one.
-    fn io<'a>(&'a mut self) -> Option<&'a mut IoFactory>;
-    fn has_active_io(&self) -> bool;
-}
-
-pub trait RemoteCallback {
-    /// Trigger the remote callback. Note that the number of times the
-    /// callback is run is not guaranteed. All that is guaranteed is
-    /// that, after calling 'fire', the callback will be called at
-    /// least once, but multiple callbacks may be coalesced and
-    /// callbacks may be called more often requested. Destruction also
-    /// triggers the callback.
-    fn fire(&mut self);
-}
-
-/// Description of what to do when a file handle is closed
-pub enum CloseBehavior {
-    /// Do not close this handle when the object is destroyed
-    DontClose,
-    /// Synchronously close the handle, meaning that the task will block when
-    /// the handle is destroyed until it has been fully closed.
-    CloseSynchronously,
-    /// Asynchronously closes a handle, meaning that the task will *not* block
-    /// when the handle is destroyed, but the handle will still get deallocated
-    /// and cleaned up (but this will happen asynchronously on the local event
-    /// loop).
-    CloseAsynchronously,
-}
-
-/// Data needed to spawn a process. Serializes the `std::io::process::Command`
-/// builder.
-pub struct ProcessConfig<'a> {
-    /// Path to the program to run.
-    pub program: &'a CString,
-
-    /// Arguments to pass to the program (doesn't include the program itself).
-    pub args: &'a [CString],
-
-    /// Optional environment to specify for the program. If this is None, then
-    /// it will inherit the current process's environment.
-    pub env: Option<&'a [(CString, CString)]>,
-
-    /// Optional working directory for the new process. If this is None, then
-    /// the current directory of the running process is inherited.
-    pub cwd: Option<&'a CString>,
-
-    /// Configuration for the child process's stdin handle (file descriptor 0).
-    /// This field defaults to `CreatePipe(true, false)` so the input can be
-    /// written to.
-    pub stdin: StdioContainer,
-
-    /// Configuration for the child process's stdout handle (file descriptor 1).
-    /// This field defaults to `CreatePipe(false, true)` so the output can be
-    /// collected.
-    pub stdout: StdioContainer,
-
-    /// Configuration for the child process's stdout handle (file descriptor 2).
-    /// This field defaults to `CreatePipe(false, true)` so the output can be
-    /// collected.
-    pub stderr: StdioContainer,
-
-    /// Any number of streams/file descriptors/pipes may be attached to this
-    /// process. This list enumerates the file descriptors and such for the
-    /// process to be spawned, and the file descriptors inherited will start at
-    /// 3 and go to the length of this array. The first three file descriptors
-    /// (stdin/stdout/stderr) are configured with the `stdin`, `stdout`, and
-    /// `stderr` fields.
-    pub extra_io: &'a [StdioContainer],
-
-    /// Sets the child process's user id. This translates to a `setuid` call in
-    /// the child process. Setting this value on windows will cause the spawn to
-    /// fail. Failure in the `setuid` call on unix will also cause the spawn to
-    /// fail.
-    pub uid: Option<uint>,
-
-    /// Similar to `uid`, but sets the group id of the child process. This has
-    /// the same semantics as the `uid` field.
-    pub gid: Option<uint>,
-
-    /// If true, the child process is spawned in a detached state. On unix, this
-    /// means that the child is the leader of a new process group.
-    pub detach: bool,
-}
-
-pub struct LocalIo<'a> {
-    factory: &'a mut IoFactory,
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for LocalIo<'a> {
-    fn drop(&mut self) {
-        // FIXME(pcwalton): Do nothing here for now, but eventually we may want
-        // something. For now this serves to make `LocalIo` noncopyable.
-    }
-}
-
-impl<'a> LocalIo<'a> {
-    /// Returns the local I/O: either the local scheduler's I/O services or
-    /// the native I/O services.
-    pub fn borrow() -> Option<LocalIo> {
-        // FIXME(#11053): bad
-        //
-        // This is currently very unsafely implemented. We don't actually
-        // *take* the local I/O so there's a very real possibility that we
-        // can have two borrows at once. Currently there is not a clear way
-        // to actually borrow the local I/O factory safely because even if
-        // ownership were transferred down to the functions that the I/O
-        // factory implements it's just too much of a pain to know when to
-        // relinquish ownership back into the local task (but that would be
-        // the safe way of implementing this function).
-        //
-        // In order to get around this, we just transmute a copy out of the task
-        // in order to have what is likely a static lifetime (bad).
-        let mut t: Box<Task> = match Local::try_take() {
-            Some(t) => t,
-            None => return None,
-        };
-        let ret = t.local_io().map(|t| {
-            unsafe { mem::transmute_copy(&t) }
-        });
-        Local::put(t);
-        return ret;
-    }
-
-    pub fn maybe_raise<T>(f: |io: &mut IoFactory| -> IoResult<T>)
-        -> IoResult<T>
-    {
-        match LocalIo::borrow() {
-            None => Err(io::standard_error(io::IoUnavailable)),
-            Some(mut io) => f(io.get()),
-        }
-    }
-
-    pub fn new<'a>(io: &'a mut IoFactory) -> LocalIo<'a> {
-        LocalIo { factory: io }
-    }
-
-    /// Returns the underlying I/O factory as a trait reference.
-    #[inline]
-    pub fn get<'a>(&'a mut self) -> &'a mut IoFactory {
-        // FIXME(pcwalton): I think this is actually sound? Could borrow check
-        // allow this safely?
-        unsafe {
-            mem::transmute_copy(&self.factory)
-        }
-    }
-}
-
-pub trait IoFactory {
-    // networking
-    fn tcp_connect(&mut self, addr: SocketAddr,
-                   timeout: Option<u64>) -> IoResult<Box<RtioTcpStream:Send>>;
-    fn tcp_bind(&mut self, addr: SocketAddr)
-                -> IoResult<Box<RtioTcpListener:Send>>;
-    fn udp_bind(&mut self, addr: SocketAddr)
-                -> IoResult<Box<RtioUdpSocket:Send>>;
-    fn unix_bind(&mut self, path: &CString)
-                 -> IoResult<Box<RtioUnixListener:Send>>;
-    fn unix_connect(&mut self, path: &CString,
-                    timeout: Option<u64>) -> IoResult<Box<RtioPipe:Send>>;
-    fn get_host_addresses(&mut self, host: Option<&str>, servname: Option<&str>,
-                          hint: Option<ai::Hint>) -> IoResult<Vec<ai::Info>>;
-
-    // filesystem operations
-    fn fs_from_raw_fd(&mut self, fd: c_int, close: CloseBehavior)
-                      -> Box<RtioFileStream:Send>;
-    fn fs_open(&mut self, path: &CString, fm: FileMode, fa: FileAccess)
-               -> IoResult<Box<RtioFileStream:Send>>;
-    fn fs_unlink(&mut self, path: &CString) -> IoResult<()>;
-    fn fs_stat(&mut self, path: &CString) -> IoResult<FileStat>;
-    fn fs_mkdir(&mut self, path: &CString,
-                mode: FilePermission) -> IoResult<()>;
-    fn fs_chmod(&mut self, path: &CString,
-                mode: FilePermission) -> IoResult<()>;
-    fn fs_rmdir(&mut self, path: &CString) -> IoResult<()>;
-    fn fs_rename(&mut self, path: &CString, to: &CString) -> IoResult<()>;
-    fn fs_readdir(&mut self, path: &CString, flags: c_int) ->
-        IoResult<Vec<CString>>;
-    fn fs_lstat(&mut self, path: &CString) -> IoResult<FileStat>;
-    fn fs_chown(&mut self, path: &CString, uid: int, gid: int) ->
-        IoResult<()>;
-    fn fs_readlink(&mut self, path: &CString) -> IoResult<CString>;
-    fn fs_symlink(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
-    fn fs_link(&mut self, src: &CString, dst: &CString) -> IoResult<()>;
-    fn fs_utime(&mut self, src: &CString, atime: u64, mtime: u64) ->
-        IoResult<()>;
-
-    // misc
-    fn timer_init(&mut self) -> IoResult<Box<RtioTimer:Send>>;
-    fn spawn(&mut self, cfg: ProcessConfig)
-            -> IoResult<(Box<RtioProcess:Send>,
-                         Vec<Option<Box<RtioPipe:Send>>>)>;
-    fn kill(&mut self, pid: libc::pid_t, signal: int) -> IoResult<()>;
-    fn pipe_open(&mut self, fd: c_int) -> IoResult<Box<RtioPipe:Send>>;
-    fn tty_open(&mut self, fd: c_int, readable: bool)
-            -> IoResult<Box<RtioTTY:Send>>;
-    fn signal(&mut self, signal: Signum, channel: Sender<Signum>)
-        -> IoResult<Box<RtioSignal:Send>>;
-}
-
-pub trait RtioTcpListener : RtioSocket {
-    fn listen(~self) -> IoResult<Box<RtioTcpAcceptor:Send>>;
-}
-
-pub trait RtioTcpAcceptor : RtioSocket {
-    fn accept(&mut self) -> IoResult<Box<RtioTcpStream:Send>>;
-    fn accept_simultaneously(&mut self) -> IoResult<()>;
-    fn dont_accept_simultaneously(&mut self) -> IoResult<()>;
-    fn set_timeout(&mut self, timeout: Option<u64>);
-}
-
-pub trait RtioTcpStream : RtioSocket {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
-    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
-    fn peer_name(&mut self) -> IoResult<SocketAddr>;
-    fn control_congestion(&mut self) -> IoResult<()>;
-    fn nodelay(&mut self) -> IoResult<()>;
-    fn keepalive(&mut self, delay_in_seconds: uint) -> IoResult<()>;
-    fn letdie(&mut self) -> IoResult<()>;
-    fn clone(&self) -> Box<RtioTcpStream:Send>;
-    fn close_write(&mut self) -> IoResult<()>;
-    fn close_read(&mut self) -> IoResult<()>;
-    fn set_timeout(&mut self, timeout_ms: Option<u64>);
-    fn set_read_timeout(&mut self, timeout_ms: Option<u64>);
-    fn set_write_timeout(&mut self, timeout_ms: Option<u64>);
-}
-
-pub trait RtioSocket {
-    fn socket_name(&mut self) -> IoResult<SocketAddr>;
-}
-
-pub trait RtioUdpSocket : RtioSocket {
-    fn recvfrom(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)>;
-    fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> IoResult<()>;
-
-    fn join_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
-    fn leave_multicast(&mut self, multi: IpAddr) -> IoResult<()>;
-
-    fn loop_multicast_locally(&mut self) -> IoResult<()>;
-    fn dont_loop_multicast_locally(&mut self) -> IoResult<()>;
-
-    fn multicast_time_to_live(&mut self, ttl: int) -> IoResult<()>;
-    fn time_to_live(&mut self, ttl: int) -> IoResult<()>;
-
-    fn hear_broadcasts(&mut self) -> IoResult<()>;
-    fn ignore_broadcasts(&mut self) -> IoResult<()>;
-
-    fn clone(&self) -> Box<RtioUdpSocket:Send>;
-    fn set_timeout(&mut self, timeout_ms: Option<u64>);
-    fn set_read_timeout(&mut self, timeout_ms: Option<u64>);
-    fn set_write_timeout(&mut self, timeout_ms: Option<u64>);
-}
-
-pub trait RtioTimer {
-    fn sleep(&mut self, msecs: u64);
-    fn oneshot(&mut self, msecs: u64) -> Receiver<()>;
-    fn period(&mut self, msecs: u64) -> Receiver<()>;
-}
-
-pub trait RtioFileStream {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<int>;
-    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
-    fn pread(&mut self, buf: &mut [u8], offset: u64) -> IoResult<int>;
-    fn pwrite(&mut self, buf: &[u8], offset: u64) -> IoResult<()>;
-    fn seek(&mut self, pos: i64, whence: SeekStyle) -> IoResult<u64>;
-    fn tell(&self) -> IoResult<u64>;
-    fn fsync(&mut self) -> IoResult<()>;
-    fn datasync(&mut self) -> IoResult<()>;
-    fn truncate(&mut self, offset: i64) -> IoResult<()>;
-    fn fstat(&mut self) -> IoResult<FileStat>;
-}
-
-pub trait RtioProcess {
-    fn id(&self) -> libc::pid_t;
-    fn kill(&mut self, signal: int) -> IoResult<()>;
-    fn wait(&mut self) -> IoResult<ProcessExit>;
-    fn set_timeout(&mut self, timeout: Option<u64>);
-}
-
-pub trait RtioPipe {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
-    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
-    fn clone(&self) -> Box<RtioPipe:Send>;
-
-    fn close_write(&mut self) -> IoResult<()>;
-    fn close_read(&mut self) -> IoResult<()>;
-    fn set_timeout(&mut self, timeout_ms: Option<u64>);
-    fn set_read_timeout(&mut self, timeout_ms: Option<u64>);
-    fn set_write_timeout(&mut self, timeout_ms: Option<u64>);
-}
-
-pub trait RtioUnixListener {
-    fn listen(~self) -> IoResult<Box<RtioUnixAcceptor:Send>>;
-}
-
-pub trait RtioUnixAcceptor {
-    fn accept(&mut self) -> IoResult<Box<RtioPipe:Send>>;
-    fn set_timeout(&mut self, timeout: Option<u64>);
-}
-
-pub trait RtioTTY {
-    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint>;
-    fn write(&mut self, buf: &[u8]) -> IoResult<()>;
-    fn set_raw(&mut self, raw: bool) -> IoResult<()>;
-    fn get_winsize(&mut self) -> IoResult<(int, int)>;
-    fn isatty(&self) -> bool;
-}
-
-pub trait PausableIdleCallback {
-    fn pause(&mut self);
-    fn resume(&mut self);
-}
-
-pub trait RtioSignal {}
diff --git a/src/libstd/rt/stack.rs b/src/libstd/rt/stack.rs
deleted file mode 100644
index dc6ab494d64..00000000000
--- a/src/libstd/rt/stack.rs
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2013 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.
-
-//! Rust stack-limit management
-//!
-//! Currently Rust uses a segmented-stack-like scheme in order to detect stack
-//! overflow for rust tasks. In this scheme, the prologue of all functions are
-//! preceded with a check to see whether the current stack limits are being
-//! exceeded.
-//!
-//! This module provides the functionality necessary in order to manage these
-//! stack limits (which are stored in platform-specific locations). The
-//! functions here are used at the borders of the task lifetime in order to
-//! manage these limits.
-//!
-//! This function is an unstable module because this scheme for stack overflow
-//! detection is not guaranteed to continue in the future. Usage of this module
-//! is discouraged unless absolutely necessary.
-
-pub static RED_ZONE: uint = 20 * 1024;
-
-/// This function is invoked from rust's current __morestack function. Segmented
-/// stacks are currently not enabled as segmented stacks, but rather one giant
-/// stack segment. This means that whenever we run out of stack, we want to
-/// truly consider it to be stack overflow rather than allocating a new stack.
-#[cfg(not(test))] // in testing, use the original libstd's version
-#[lang = "stack_exhausted"]
-extern fn stack_exhausted() {
-    use option::{Option, None, Some};
-    use owned::Box;
-    use rt::local::Local;
-    use rt::task::Task;
-    use str::Str;
-    use intrinsics;
-
-    unsafe {
-        // We're calling this function because the stack just ran out. We need
-        // to call some other rust functions, but if we invoke the functions
-        // right now it'll just trigger this handler being called again. In
-        // order to alleviate this, we move the stack limit to be inside of the
-        // red zone that was allocated for exactly this reason.
-        let limit = get_sp_limit();
-        record_sp_limit(limit - RED_ZONE / 2);
-
-        // This probably isn't the best course of action. Ideally one would want
-        // to unwind the stack here instead of just aborting the entire process.
-        // This is a tricky problem, however. There's a few things which need to
-        // be considered:
-        //
-        //  1. We're here because of a stack overflow, yet unwinding will run
-        //     destructors and hence arbitrary code. What if that code overflows
-        //     the stack? One possibility is to use the above allocation of an
-        //     extra 10k to hope that we don't hit the limit, and if we do then
-        //     abort the whole program. Not the best, but kind of hard to deal
-        //     with unless we want to switch stacks.
-        //
-        //  2. LLVM will optimize functions based on whether they can unwind or
-        //     not. It will flag functions with 'nounwind' if it believes that
-        //     the function cannot trigger unwinding, but if we do unwind on
-        //     stack overflow then it means that we could unwind in any function
-        //     anywhere. We would have to make sure that LLVM only places the
-        //     nounwind flag on functions which don't call any other functions.
-        //
-        //  3. The function that overflowed may have owned arguments. These
-        //     arguments need to have their destructors run, but we haven't even
-        //     begun executing the function yet, so unwinding will not run the
-        //     any landing pads for these functions. If this is ignored, then
-        //     the arguments will just be leaked.
-        //
-        // Exactly what to do here is a very delicate topic, and is possibly
-        // still up in the air for what exactly to do. Some relevant issues:
-        //
-        //  #3555 - out-of-stack failure leaks arguments
-        //  #3695 - should there be a stack limit?
-        //  #9855 - possible strategies which could be taken
-        //  #9854 - unwinding on windows through __morestack has never worked
-        //  #2361 - possible implementation of not using landing pads
-
-        let task: Option<Box<Task>> = Local::try_take();
-        let name = match task {
-            Some(ref task) => {
-                task.name.as_ref().map(|n| n.as_slice())
-            }
-            None => None
-        };
-        let name = name.unwrap_or("<unknown>");
-
-        // See the message below for why this is not emitted to the
-        // task's logger. This has the additional conundrum of the
-        // logger may not be initialized just yet, meaning that an FFI
-        // call would happen to initialized it (calling out to libuv),
-        // and the FFI call needs 2MB of stack when we just ran out.
-        rterrln!("task '{}' has overflowed its stack", name);
-
-        intrinsics::abort();
-    }
-}
-
-#[inline(always)]
-pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-    // When the old runtime had segmented stacks, it used a calculation that was
-    // "limit + RED_ZONE + FUDGE". The red zone was for things like dynamic
-    // symbol resolution, llvm function calls, etc. In theory this red zone
-    // value is 0, but it matters far less when we have gigantic stacks because
-    // we don't need to be so exact about our stack budget. The "fudge factor"
-    // was because LLVM doesn't emit a stack check for functions < 256 bytes in
-    // size. Again though, we have giant stacks, so we round all these
-    // calculations up to the nice round number of 20k.
-    record_sp_limit(stack_lo + RED_ZONE);
-
-    return target_record_stack_bounds(stack_lo, stack_hi);
-
-    #[cfg(not(windows))] #[cfg(not(target_arch = "x86_64"))] #[inline(always)]
-    unsafe fn target_record_stack_bounds(_stack_lo: uint, _stack_hi: uint) {}
-    #[cfg(windows, target_arch = "x86_64")] #[inline(always)]
-    unsafe fn target_record_stack_bounds(stack_lo: uint, stack_hi: uint) {
-        // Windows compiles C functions which may check the stack bounds. This
-        // means that if we want to perform valid FFI on windows, then we need
-        // to ensure that the stack bounds are what they truly are for this
-        // task. More info can be found at:
-        //   https://github.com/mozilla/rust/issues/3445#issuecomment-26114839
-        //
-        // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
-        asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
-        asm!("mov $0, %gs:0x10" :: "r"(stack_lo) :: "volatile");
-    }
-}
-
-/// Records the current limit of the stack as specified by `end`.
-///
-/// This is stored in an OS-dependent location, likely inside of the thread
-/// local storage. The location that the limit is stored is a pre-ordained
-/// location because it's where LLVM has emitted code to check.
-///
-/// Note that this cannot be called under normal circumstances. This function is
-/// changing the stack limit, so upon returning any further function calls will
-/// possibly be triggering the morestack logic if you're not careful.
-///
-/// Also note that this and all of the inside functions are all flagged as
-/// "inline(always)" because they're messing around with the stack limits.  This
-/// would be unfortunate for the functions themselves to trigger a morestack
-/// invocation (if they were an actual function call).
-#[inline(always)]
-pub unsafe fn record_sp_limit(limit: uint) {
-    return target_record_sp_limit(limit);
-
-    // x86-64
-    #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        asm!("movq $$0x60+90*8, %rsi
-              movq $0, %gs:(%rsi)" :: "r"(limit) : "rsi" : "volatile")
-    }
-    #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        asm!("movq $0, %fs:112" :: "r"(limit) :: "volatile")
-    }
-    #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
-        // store this inside of the "arbitrary data slot", but double the size
-        // because this is 64 bit instead of 32 bit
-        asm!("movq $0, %gs:0x28" :: "r"(limit) :: "volatile")
-    }
-    #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        asm!("movq $0, %fs:24" :: "r"(limit) :: "volatile")
-    }
-
-    // x86
-    #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        asm!("movl $$0x48+90*4, %eax
-              movl $0, %gs:(%eax)" :: "r"(limit) : "eax" : "volatile")
-    }
-    #[cfg(target_arch = "x86", target_os = "linux")]
-    #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        asm!("movl $0, %gs:48" :: "r"(limit) :: "volatile")
-    }
-    #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        // see: http://en.wikipedia.org/wiki/Win32_Thread_Information_Block
-        // store this inside of the "arbitrary data slot"
-        asm!("movl $0, %fs:0x14" :: "r"(limit) :: "volatile")
-    }
-
-    // mips, arm - Some brave soul can port these to inline asm, but it's over
-    //             my head personally
-    #[cfg(target_arch = "mips")]
-    #[cfg(target_arch = "arm")] #[inline(always)]
-    unsafe fn target_record_sp_limit(limit: uint) {
-        use libc::c_void;
-        return record_sp_limit(limit as *c_void);
-        extern {
-            fn record_sp_limit(limit: *c_void);
-        }
-    }
-}
-
-/// The counterpart of the function above, this function will fetch the current
-/// stack limit stored in TLS.
-///
-/// Note that all of these functions are meant to be exact counterparts of their
-/// brethren above, except that the operands are reversed.
-///
-/// As with the setter, this function does not have a __morestack header and can
-/// therefore be called in a "we're out of stack" situation.
-#[inline(always)]
-pub unsafe fn get_sp_limit() -> uint {
-    return target_get_sp_limit();
-
-    // x86-64
-    #[cfg(target_arch = "x86_64", target_os = "macos")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movq $$0x60+90*8, %rsi
-              movq %gs:(%rsi), $0" : "=r"(limit) :: "rsi" : "volatile");
-        return limit;
-    }
-    #[cfg(target_arch = "x86_64", target_os = "linux")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movq %fs:112, $0" : "=r"(limit) ::: "volatile");
-        return limit;
-    }
-    #[cfg(target_arch = "x86_64", target_os = "win32")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movq %gs:0x28, $0" : "=r"(limit) ::: "volatile");
-        return limit;
-    }
-    #[cfg(target_arch = "x86_64", target_os = "freebsd")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movq %fs:24, $0" : "=r"(limit) ::: "volatile");
-        return limit;
-    }
-
-    // x86
-    #[cfg(target_arch = "x86", target_os = "macos")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movl $$0x48+90*4, %eax
-              movl %gs:(%eax), $0" : "=r"(limit) :: "eax" : "volatile");
-        return limit;
-    }
-    #[cfg(target_arch = "x86", target_os = "linux")]
-    #[cfg(target_arch = "x86", target_os = "freebsd")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movl %gs:48, $0" : "=r"(limit) ::: "volatile");
-        return limit;
-    }
-    #[cfg(target_arch = "x86", target_os = "win32")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        let limit;
-        asm!("movl %fs:0x14, $0" : "=r"(limit) ::: "volatile");
-        return limit;
-    }
-
-    // mips, arm - Some brave soul can port these to inline asm, but it's over
-    //             my head personally
-    #[cfg(target_arch = "mips")]
-    #[cfg(target_arch = "arm")] #[inline(always)]
-    unsafe fn target_get_sp_limit() -> uint {
-        use libc::c_void;
-        return get_sp_limit() as uint;
-        extern {
-            fn get_sp_limit() -> *c_void;
-        }
-    }
-}
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
deleted file mode 100644
index 7f492a00b80..00000000000
--- a/src/libstd/rt/task.rs
+++ /dev/null
@@ -1,500 +0,0 @@
-// Copyright 2013-2014 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.
-
-//! Language-level runtime services that should reasonably expected
-//! to be available 'everywhere'. Local heaps, GC, unwinding,
-//! local storage, and logging. Even a 'freestanding' Rust would likely want
-//! to implement this.
-
-use alloc::arc::Arc;
-
-use cleanup;
-use clone::Clone;
-use comm::Sender;
-use io::Writer;
-use iter::{Iterator, Take};
-use kinds::Send;
-use local_data;
-use mem;
-use ops::Drop;
-use option::{Option, Some, None};
-use owned::{AnyOwnExt, Box};
-use prelude::drop;
-use result::{Result, Ok, Err};
-use rt::Runtime;
-use rt::local::Local;
-use rt::local_heap::LocalHeap;
-use rt::rtio::LocalIo;
-use rt::unwind::Unwinder;
-use str::SendStr;
-use sync::atomics::{AtomicUint, SeqCst};
-use task::{TaskResult, TaskOpts};
-use finally::Finally;
-
-/// The Task struct represents all state associated with a rust
-/// task. There are at this point two primary "subtypes" of task,
-/// however instead of using a subtype we just have a "task_type" field
-/// in the struct. This contains a pointer to another struct that holds
-/// the type-specific state.
-pub struct Task {
-    pub heap: LocalHeap,
-    pub gc: GarbageCollector,
-    pub storage: LocalStorage,
-    pub unwinder: Unwinder,
-    pub death: Death,
-    pub destroyed: bool,
-    pub name: Option<SendStr>,
-
-    pub stdout: Option<Box<Writer:Send>>,
-    pub stderr: Option<Box<Writer:Send>>,
-
-    imp: Option<Box<Runtime:Send>>,
-}
-
-pub struct GarbageCollector;
-pub struct LocalStorage(pub Option<local_data::Map>);
-
-/// A handle to a blocked task. Usually this means having the Box<Task>
-/// pointer by ownership, but if the task is killable, a killer can steal it
-/// at any time.
-pub enum BlockedTask {
-    Owned(Box<Task>),
-    Shared(Arc<AtomicUint>),
-}
-
-pub enum DeathAction {
-    /// Action to be done with the exit code. If set, also makes the task wait
-    /// until all its watched children exit before collecting the status.
-    Execute(proc(TaskResult):Send),
-    /// A channel to send the result of the task on when the task exits
-    SendMessage(Sender<TaskResult>),
-}
-
-/// Per-task state related to task death, killing, failure, etc.
-pub struct Death {
-    pub on_exit: Option<DeathAction>,
-}
-
-pub struct BlockedTasks {
-    inner: Arc<AtomicUint>,
-}
-
-impl Task {
-    pub fn new() -> Task {
-        Task {
-            heap: LocalHeap::new(),
-            gc: GarbageCollector,
-            storage: LocalStorage(None),
-            unwinder: Unwinder::new(),
-            death: Death::new(),
-            destroyed: false,
-            name: None,
-            stdout: None,
-            stderr: None,
-            imp: None,
-        }
-    }
-
-    /// Executes the given closure as if it's running inside this task. The task
-    /// is consumed upon entry, and the destroyed task is returned from this
-    /// function in order for the caller to free. This function is guaranteed to
-    /// not unwind because the closure specified is run inside of a `rust_try`
-    /// block. (this is the only try/catch block in the world).
-    ///
-    /// This function is *not* meant to be abused as a "try/catch" block. This
-    /// is meant to be used at the absolute boundaries of a task's lifetime, and
-    /// only for that purpose.
-    pub fn run(~self, mut f: ||) -> Box<Task> {
-        // Need to put ourselves into TLS, but also need access to the unwinder.
-        // Unsafely get a handle to the task so we can continue to use it after
-        // putting it in tls (so we can invoke the unwinder).
-        let handle: *mut Task = unsafe {
-            *mem::transmute::<&Box<Task>, &*mut Task>(&self)
-        };
-        Local::put(self);
-
-        // The only try/catch block in the world. Attempt to run the task's
-        // client-specified code and catch any failures.
-        let try_block = || {
-
-            // Run the task main function, then do some cleanup.
-            f.finally(|| {
-                #[allow(unused_must_use)]
-                fn close_outputs() {
-                    let mut task = Local::borrow(None::<Task>);
-                    let stderr = task.stderr.take();
-                    let stdout = task.stdout.take();
-                    drop(task);
-                    match stdout { Some(mut w) => { w.flush(); }, None => {} }
-                    match stderr { Some(mut w) => { w.flush(); }, None => {} }
-                }
-
-                // First, flush/destroy the user stdout/logger because these
-                // destructors can run arbitrary code.
-                close_outputs();
-
-                // First, destroy task-local storage. This may run user dtors.
-                //
-                // FIXME #8302: Dear diary. I'm so tired and confused.
-                // There's some interaction in rustc between the box
-                // annihilator and the TLS dtor by which TLS is
-                // accessed from annihilated box dtors *after* TLS is
-                // destroyed. Somehow setting TLS back to null, as the
-                // old runtime did, makes this work, but I don't currently
-                // understand how. I would expect that, if the annihilator
-                // reinvokes TLS while TLS is uninitialized, that
-                // TLS would be reinitialized but never destroyed,
-                // but somehow this works. I have no idea what's going
-                // on but this seems to make things magically work. FML.
-                //
-                // (added after initial comment) A possible interaction here is
-                // that the destructors for the objects in TLS themselves invoke
-                // TLS, or possibly some destructors for those objects being
-                // annihilated invoke TLS. Sadly these two operations seemed to
-                // be intertwined, and miraculously work for now...
-                let mut task = Local::borrow(None::<Task>);
-                let storage_map = {
-                    let &LocalStorage(ref mut optmap) = &mut task.storage;
-                    optmap.take()
-                };
-                drop(task);
-                drop(storage_map);
-
-                // Destroy remaining boxes. Also may run user dtors.
-                unsafe { cleanup::annihilate(); }
-
-                // Finally, just in case user dtors printed/logged during TLS
-                // cleanup and annihilation, re-destroy stdout and the logger.
-                // Note that these will have been initialized with a
-                // runtime-provided type which we have control over what the
-                // destructor does.
-                close_outputs();
-            })
-        };
-
-        unsafe { (*handle).unwinder.try(try_block); }
-
-        // Here we must unsafely borrow the task in order to not remove it from
-        // TLS. When collecting failure, we may attempt to send on a channel (or
-        // just run aribitrary code), so we must be sure to still have a local
-        // task in TLS.
-        unsafe {
-            let me: *mut Task = Local::unsafe_borrow();
-            (*me).death.collect_failure((*me).unwinder.result());
-        }
-        let mut me: Box<Task> = Local::take();
-        me.destroyed = true;
-        return me;
-    }
-
-    /// Inserts a runtime object into this task, transferring ownership to the
-    /// task. It is illegal to replace a previous runtime object in this task
-    /// with this argument.
-    pub fn put_runtime(&mut self, ops: Box<Runtime:Send>) {
-        assert!(self.imp.is_none());
-        self.imp = Some(ops);
-    }
-
-    /// Attempts to extract the runtime as a specific type. If the runtime does
-    /// not have the provided type, then the runtime is not removed. If the
-    /// runtime does have the specified type, then it is removed and returned
-    /// (transfer of ownership).
-    ///
-    /// It is recommended to only use this method when *absolutely necessary*.
-    /// This function may not be available in the future.
-    pub fn maybe_take_runtime<T: 'static>(&mut self) -> Option<Box<T>> {
-        // This is a terrible, terrible function. The general idea here is to
-        // take the runtime, cast it to Box<Any>, check if it has the right
-        // type, and then re-cast it back if necessary. The method of doing
-        // this is pretty sketchy and involves shuffling vtables of trait
-        // objects around, but it gets the job done.
-        //
-        // FIXME: This function is a serious code smell and should be avoided at
-        //      all costs. I have yet to think of a method to avoid this
-        //      function, and I would be saddened if more usage of the function
-        //      crops up.
-        unsafe {
-            let imp = self.imp.take_unwrap();
-            let &(vtable, _): &(uint, uint) = mem::transmute(&imp);
-            match imp.wrap().move::<T>() {
-                Ok(t) => Some(t),
-                Err(t) => {
-                    let (_, obj): (uint, uint) = mem::transmute(t);
-                    let obj: Box<Runtime:Send> =
-                        mem::transmute((vtable, obj));
-                    self.put_runtime(obj);
-                    None
-                }
-            }
-        }
-    }
-
-    /// Spawns a sibling to this task. The newly spawned task is configured with
-    /// the `opts` structure and will run `f` as the body of its code.
-    pub fn spawn_sibling(mut ~self, opts: TaskOpts, f: proc():Send) {
-        let ops = self.imp.take_unwrap();
-        ops.spawn_sibling(self, opts, f)
-    }
-
-    /// Deschedules the current task, invoking `f` `amt` times. It is not
-    /// recommended to use this function directly, but rather communication
-    /// primitives in `std::comm` should be used.
-    pub fn deschedule(mut ~self, amt: uint,
-                      f: |BlockedTask| -> Result<(), BlockedTask>) {
-        let ops = self.imp.take_unwrap();
-        ops.deschedule(amt, self, f)
-    }
-
-    /// Wakes up a previously blocked task, optionally specifying whether the
-    /// current task can accept a change in scheduling. This function can only
-    /// be called on tasks that were previously blocked in `deschedule`.
-    pub fn reawaken(mut ~self) {
-        let ops = self.imp.take_unwrap();
-        ops.reawaken(self);
-    }
-
-    /// Yields control of this task to another task. This function will
-    /// eventually return, but possibly not immediately. This is used as an
-    /// opportunity to allow other tasks a chance to run.
-    pub fn yield_now(mut ~self) {
-        let ops = self.imp.take_unwrap();
-        ops.yield_now(self);
-    }
-
-    /// Similar to `yield_now`, except that this function may immediately return
-    /// without yielding (depending on what the runtime decides to do).
-    pub fn maybe_yield(mut ~self) {
-        let ops = self.imp.take_unwrap();
-        ops.maybe_yield(self);
-    }
-
-    /// Acquires a handle to the I/O factory that this task contains, normally
-    /// stored in the task's runtime. This factory may not always be available,
-    /// which is why the return type is `Option`
-    pub fn local_io<'a>(&'a mut self) -> Option<LocalIo<'a>> {
-        self.imp.get_mut_ref().local_io()
-    }
-
-    /// Returns the stack bounds for this task in (lo, hi) format. The stack
-    /// bounds may not be known for all tasks, so the return value may be
-    /// `None`.
-    pub fn stack_bounds(&self) -> (uint, uint) {
-        self.imp.get_ref().stack_bounds()
-    }
-
-    /// Returns whether it is legal for this task to block the OS thread that it
-    /// is running on.
-    pub fn can_block(&self) -> bool {
-        self.imp.get_ref().can_block()
-    }
-}
-
-impl Drop for Task {
-    fn drop(&mut self) {
-        rtdebug!("called drop for a task: {}", self as *mut Task as uint);
-        rtassert!(self.destroyed);
-    }
-}
-
-impl Iterator<BlockedTask> for BlockedTasks {
-    fn next(&mut self) -> Option<BlockedTask> {
-        Some(Shared(self.inner.clone()))
-    }
-}
-
-impl BlockedTask {
-    /// Returns Some if the task was successfully woken; None if already killed.
-    pub fn wake(self) -> Option<Box<Task>> {
-        match self {
-            Owned(task) => Some(task),
-            Shared(arc) => {
-                match arc.swap(0, SeqCst) {
-                    0 => None,
-                    n => Some(unsafe { mem::transmute(n) }),
-                }
-            }
-        }
-    }
-
-    /// Reawakens this task if ownership is acquired. If finer-grained control
-    /// is desired, use `wake` instead.
-    pub fn reawaken(self) {
-        self.wake().map(|t| t.reawaken());
-    }
-
-    // This assertion has two flavours because the wake involves an atomic op.
-    // In the faster version, destructors will fail dramatically instead.
-    #[cfg(not(test))] pub fn trash(self) { }
-    #[cfg(test)]      pub fn trash(self) { assert!(self.wake().is_none()); }
-
-    /// Create a blocked task, unless the task was already killed.
-    pub fn block(task: Box<Task>) -> BlockedTask {
-        Owned(task)
-    }
-
-    /// Converts one blocked task handle to a list of many handles to the same.
-    pub fn make_selectable(self, num_handles: uint) -> Take<BlockedTasks> {
-        let arc = match self {
-            Owned(task) => {
-                let flag = unsafe { AtomicUint::new(mem::transmute(task)) };
-                Arc::new(flag)
-            }
-            Shared(arc) => arc.clone(),
-        };
-        BlockedTasks{ inner: arc }.take(num_handles)
-    }
-
-    /// Convert to an unsafe uint value. Useful for storing in a pipe's state
-    /// flag.
-    #[inline]
-    pub unsafe fn cast_to_uint(self) -> uint {
-        match self {
-            Owned(task) => {
-                let blocked_task_ptr: uint = mem::transmute(task);
-                rtassert!(blocked_task_ptr & 0x1 == 0);
-                blocked_task_ptr
-            }
-            Shared(arc) => {
-                let blocked_task_ptr: uint = mem::transmute(box arc);
-                rtassert!(blocked_task_ptr & 0x1 == 0);
-                blocked_task_ptr | 0x1
-            }
-        }
-    }
-
-    /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
-    /// flag.
-    #[inline]
-    pub unsafe fn cast_from_uint(blocked_task_ptr: uint) -> BlockedTask {
-        if blocked_task_ptr & 0x1 == 0 {
-            Owned(mem::transmute(blocked_task_ptr))
-        } else {
-            let ptr: Box<Arc<AtomicUint>> =
-                mem::transmute(blocked_task_ptr & !1);
-            Shared(*ptr)
-        }
-    }
-}
-
-impl Death {
-    pub fn new() -> Death {
-        Death { on_exit: None, }
-    }
-
-    /// Collect failure exit codes from children and propagate them to a parent.
-    pub fn collect_failure(&mut self, result: TaskResult) {
-        match self.on_exit.take() {
-            Some(Execute(f)) => f(result),
-            Some(SendMessage(ch)) => { let _ = ch.send_opt(result); }
-            None => {}
-        }
-    }
-}
-
-impl Drop for Death {
-    fn drop(&mut self) {
-        // make this type noncopyable
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-    use prelude::*;
-    use task;
-
-    #[test]
-    fn local_heap() {
-        let a = @5;
-        let b = a;
-        assert!(*a == 5);
-        assert!(*b == 5);
-    }
-
-    #[test]
-    fn tls() {
-        local_data_key!(key: @String)
-        key.replace(Some(@"data".to_string()));
-        assert_eq!(key.get().unwrap().as_slice(), "data");
-        local_data_key!(key2: @String)
-        key2.replace(Some(@"data".to_string()));
-        assert_eq!(key2.get().unwrap().as_slice(), "data");
-    }
-
-    #[test]
-    fn unwind() {
-        let result = task::try(proc()());
-        rtdebug!("trying first assert");
-        assert!(result.is_ok());
-        let result = task::try::<()>(proc() fail!());
-        rtdebug!("trying second assert");
-        assert!(result.is_err());
-    }
-
-    #[test]
-    fn rng() {
-        use rand::{StdRng, Rng};
-        let mut r = StdRng::new().ok().unwrap();
-        let _ = r.next_u32();
-    }
-
-    #[test]
-    fn logging() {
-        info!("here i am. logging in a newsched task");
-    }
-
-    #[test]
-    fn comm_stream() {
-        let (tx, rx) = channel();
-        tx.send(10);
-        assert!(rx.recv() == 10);
-    }
-
-    #[test]
-    fn comm_shared_chan() {
-        let (tx, rx) = channel();
-        tx.send(10);
-        assert!(rx.recv() == 10);
-    }
-
-    #[test]
-    fn heap_cycles() {
-        use cell::RefCell;
-        use option::{Option, Some, None};
-
-        struct List {
-            next: Option<@RefCell<List>>,
-        }
-
-        let a = @RefCell::new(List { next: None });
-        let b = @RefCell::new(List { next: Some(a) });
-
-        {
-            let mut a = a.borrow_mut();
-            a.next = Some(b);
-        }
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_begin_unwind() {
-        use rt::unwind::begin_unwind;
-        begin_unwind("cause", file!(), line!())
-    }
-
-    // Task blocking tests
-
-    #[test]
-    fn block_and_wake() {
-        let task = box Task::new();
-        let mut task = BlockedTask::block(task).wake().unwrap();
-        task.destroyed = true;
-    }
-}
diff --git a/src/libstd/rt/thread_local_storage.rs b/src/libstd/rt/thread_local_storage.rs
deleted file mode 100644
index a3ebcbafff8..00000000000
--- a/src/libstd/rt/thread_local_storage.rs
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2013-2014 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.
-
-#![allow(dead_code)]
-
-#[cfg(test)]
-use owned::Box;
-#[cfg(unix)]
-use libc::c_int;
-#[cfg(unix)]
-use ptr::null;
-#[cfg(windows)]
-use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
-
-#[cfg(unix)]
-pub type Key = pthread_key_t;
-
-#[cfg(unix)]
-pub unsafe fn create(key: &mut Key) {
-    assert_eq!(0, pthread_key_create(key, null()));
-}
-
-#[cfg(unix)]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    assert_eq!(0, pthread_setspecific(key, value));
-}
-
-#[cfg(unix)]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    pthread_getspecific(key)
-}
-
-#[cfg(unix)]
-pub unsafe fn destroy(key: Key) {
-    assert_eq!(0, pthread_key_delete(key));
-}
-
-#[cfg(target_os="macos")]
-#[allow(non_camel_case_types)] // foreign type
-type pthread_key_t = ::libc::c_ulong;
-
-#[cfg(target_os="linux")]
-#[cfg(target_os="freebsd")]
-#[cfg(target_os="android")]
-#[allow(non_camel_case_types)] // foreign type
-type pthread_key_t = ::libc::c_uint;
-
-#[cfg(unix)]
-extern {
-    fn pthread_key_create(key: *mut pthread_key_t, dtor: *u8) -> c_int;
-    fn pthread_key_delete(key: pthread_key_t) -> c_int;
-    fn pthread_getspecific(key: pthread_key_t) -> *mut u8;
-    fn pthread_setspecific(key: pthread_key_t, value: *mut u8) -> c_int;
-}
-
-#[cfg(windows)]
-pub type Key = DWORD;
-
-#[cfg(windows)]
-pub unsafe fn create(key: &mut Key) {
-    static TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
-    *key = TlsAlloc();
-    assert!(*key != TLS_OUT_OF_INDEXES);
-}
-
-#[cfg(windows)]
-pub unsafe fn set(key: Key, value: *mut u8) {
-    assert!(0 != TlsSetValue(key, value as *mut ::libc::c_void))
-}
-
-#[cfg(windows)]
-pub unsafe fn get(key: Key) -> *mut u8 {
-    TlsGetValue(key) as *mut u8
-}
-
-#[cfg(windows)]
-pub unsafe fn destroy(key: Key) {
-    assert!(TlsFree(key) != 0);
-}
-
-#[cfg(windows)]
-#[allow(non_snake_case_functions)]
-extern "system" {
-    fn TlsAlloc() -> DWORD;
-    fn TlsFree(dwTlsIndex: DWORD) -> BOOL;
-    fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
-    fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
-}
-
-#[test]
-fn tls_smoke_test() {
-    use mem::transmute;
-    unsafe {
-        let mut key = 0;
-        let value = box 20;
-        create(&mut key);
-        set(key, transmute(value));
-        let value: Box<int> = transmute(get(key));
-        assert_eq!(value, box 20);
-        let value = box 30;
-        set(key, transmute(value));
-        let value: Box<int> = transmute(get(key));
-        assert_eq!(value, box 30);
-    }
-}
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
deleted file mode 100644
index af73e6167af..00000000000
--- a/src/libstd/rt/unwind.rs
+++ /dev/null
@@ -1,494 +0,0 @@
-// Copyright 2013 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.
-
-//! Stack unwinding
-
-// Implementation of Rust stack unwinding
-//
-// For background on exception handling and stack unwinding please see
-// "Exception Handling in LLVM" (llvm.org/docs/ExceptionHandling.html) and
-// documents linked from it.
-// These are also good reads:
-//     http://theofilos.cs.columbia.edu/blog/2013/09/22/base_abi/
-//     http://monoinfinito.wordpress.com/series/exception-handling-in-c/
-//     http://www.airs.com/blog/index.php?s=exception+frames
-//
-// ~~~ A brief summary ~~~
-// Exception handling happens in two phases: a search phase and a cleanup phase.
-//
-// In both phases the unwinder walks stack frames from top to bottom using
-// information from the stack frame unwind sections of the current process's
-// modules ("module" here refers to an OS module, i.e. an executable or a
-// dynamic library).
-//
-// For each stack frame, it invokes the associated "personality routine", whose
-// address is also stored in the unwind info section.
-//
-// In the search phase, the job of a personality routine is to examine exception
-// object being thrown, and to decide whether it should be caught at that stack
-// frame.  Once the handler frame has been identified, cleanup phase begins.
-//
-// In the cleanup phase, personality routines invoke cleanup code associated
-// with their stack frames (i.e. destructors).  Once stack has been unwound down
-// to the handler frame level, unwinding stops and the last personality routine
-// transfers control to its' catch block.
-//
-// ~~~ Frame unwind info registration ~~~
-// Each module has its' own frame unwind info section (usually ".eh_frame"), and
-// unwinder needs to know about all of them in order for unwinding to be able to
-// cross module boundaries.
-//
-// On some platforms, like Linux, this is achieved by dynamically enumerating
-// currently loaded modules via the dl_iterate_phdr() API and finding all
-// .eh_frame sections.
-//
-// Others, like Windows, require modules to actively register their unwind info
-// sections by calling __register_frame_info() API at startup.  In the latter
-// case it is essential that there is only one copy of the unwinder runtime in
-// the process.  This is usually achieved by linking to the dynamic version of
-// the unwind runtime.
-//
-// Currently Rust uses unwind runtime provided by libgcc.
-
-use any::{Any, AnyRefExt};
-use fmt;
-use intrinsics;
-use kinds::Send;
-use mem;
-use option::{Some, None, Option};
-use owned::Box;
-use prelude::drop;
-use ptr::RawPtr;
-use result::{Err, Ok, Result};
-use rt::backtrace;
-use rt::local::Local;
-use rt::task::Task;
-use str::Str;
-use string::String;
-use task::TaskResult;
-
-use uw = rt::libunwind;
-
-pub struct Unwinder {
-    unwinding: bool,
-    cause: Option<Box<Any:Send>>
-}
-
-struct Exception {
-    uwe: uw::_Unwind_Exception,
-    cause: Option<Box<Any:Send>>,
-}
-
-impl Unwinder {
-    pub fn new() -> Unwinder {
-        Unwinder {
-            unwinding: false,
-            cause: None,
-        }
-    }
-
-    pub fn unwinding(&self) -> bool {
-        self.unwinding
-    }
-
-    pub fn try(&mut self, f: ||) {
-        self.cause = unsafe { try(f) }.err();
-    }
-
-    pub fn result(&mut self) -> TaskResult {
-        if self.unwinding {
-            Err(self.cause.take().unwrap())
-        } else {
-            Ok(())
-        }
-    }
-}
-
-/// Invoke a closure, capturing the cause of failure if one occurs.
-///
-/// This function will return `None` if the closure did not fail, and will
-/// return `Some(cause)` if the closure fails. The `cause` returned is the
-/// object with which failure was originally invoked.
-///
-/// This function also is unsafe for a variety of reasons:
-///
-/// * This is not safe to call in a nested fashion. The unwinding
-///   interface for Rust is designed to have at most one try/catch block per
-///   task, not multiple. No runtime checking is currently performed to uphold
-///   this invariant, so this function is not safe. A nested try/catch block
-///   may result in corruption of the outer try/catch block's state, especially
-///   if this is used within a task itself.
-///
-/// * It is not sound to trigger unwinding while already unwinding. Rust tasks
-///   have runtime checks in place to ensure this invariant, but it is not
-///   guaranteed that a rust task is in place when invoking this function.
-///   Unwinding twice can lead to resource leaks where some destructors are not
-///   run.
-pub unsafe fn try(f: ||) -> Result<(), Box<Any:Send>> {
-    use raw::Closure;
-    use libc::{c_void};
-
-    let closure: Closure = mem::transmute(f);
-    let ep = rust_try(try_fn, closure.code as *c_void,
-                      closure.env as *c_void);
-    return if ep.is_null() {
-        Ok(())
-    } else {
-        let my_ep = ep as *mut Exception;
-        rtdebug!("caught {}", (*my_ep).uwe.exception_class);
-        let cause = (*my_ep).cause.take();
-        uw::_Unwind_DeleteException(ep);
-        Err(cause.unwrap())
-    };
-
-    extern fn try_fn(code: *c_void, env: *c_void) {
-        unsafe {
-            let closure: || = mem::transmute(Closure {
-                code: code as *(),
-                env: env as *(),
-            });
-            closure();
-        }
-    }
-
-    extern {
-        // Rust's try-catch
-        // When f(...) returns normally, the return value is null.
-        // When f(...) throws, the return value is a pointer to the caught
-        // exception object.
-        fn rust_try(f: extern "C" fn(*c_void, *c_void),
-                    code: *c_void,
-                    data: *c_void) -> *uw::_Unwind_Exception;
-    }
-}
-
-// An uninlined, unmangled function upon which to slap yer breakpoints
-#[inline(never)]
-#[no_mangle]
-fn rust_fail(cause: Box<Any:Send>) -> ! {
-    rtdebug!("begin_unwind()");
-
-    unsafe {
-        let exception = box Exception {
-            uwe: uw::_Unwind_Exception {
-                exception_class: rust_exception_class(),
-                exception_cleanup: exception_cleanup,
-                private: [0, ..uw::unwinder_private_data_size],
-            },
-            cause: Some(cause),
-        };
-        let error = uw::_Unwind_RaiseException(mem::transmute(exception));
-        rtabort!("Could not unwind stack, error = {}", error as int)
-    }
-
-    extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
-                                exception: *uw::_Unwind_Exception) {
-        rtdebug!("exception_cleanup()");
-        unsafe {
-            let _: Box<Exception> = mem::transmute(exception);
-        }
-    }
-}
-
-// Rust's exception class identifier.  This is used by personality routines to
-// determine whether the exception was thrown by their own runtime.
-fn rust_exception_class() -> uw::_Unwind_Exception_Class {
-    // M O Z \0  R U S T -- vendor, language
-    0x4d4f5a_00_52555354
-}
-
-// We could implement our personality routine in pure Rust, however exception
-// info decoding is tedious.  More importantly, personality routines have to
-// handle various platform quirks, which are not fun to maintain.  For this
-// reason, we attempt to reuse personality routine of the C language:
-// __gcc_personality_v0.
-//
-// Since C does not support exception catching, __gcc_personality_v0 simply
-// always returns _URC_CONTINUE_UNWIND in search phase, and always returns
-// _URC_INSTALL_CONTEXT (i.e. "invoke cleanup code") in cleanup phase.
-//
-// This is pretty close to Rust's exception handling approach, except that Rust
-// does have a single "catch-all" handler at the bottom of each task's stack.
-// So we have two versions:
-// - rust_eh_personality, used by all cleanup landing pads, which never catches,
-//   so the behavior of __gcc_personality_v0 is perfectly adequate there, and
-// - rust_eh_personality_catch, used only by rust_try(), which always catches.
-//   This is achieved by overriding the return value in search phase to always
-//   say "catch!".
-
-#[cfg(not(target_arch = "arm"), not(test))]
-#[doc(hidden)]
-#[allow(visible_private_types)]
-pub mod eabi {
-    use uw = rt::libunwind;
-    use libc::c_int;
-
-    extern "C" {
-        fn __gcc_personality_v0(version: c_int,
-                                actions: uw::_Unwind_Action,
-                                exception_class: uw::_Unwind_Exception_Class,
-                                ue_header: *uw::_Unwind_Exception,
-                                context: *uw::_Unwind_Context)
-            -> uw::_Unwind_Reason_Code;
-    }
-
-    #[lang="eh_personality"]
-    extern fn eh_personality(
-        version: c_int,
-        actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *uw::_Unwind_Exception,
-        context: *uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        unsafe {
-            __gcc_personality_v0(version, actions, exception_class, ue_header,
-                                 context)
-        }
-    }
-
-    #[no_mangle] // referenced from rust_try.ll
-    pub extern "C" fn rust_eh_personality_catch(
-        version: c_int,
-        actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *uw::_Unwind_Exception,
-        context: *uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
-            uw::_URC_HANDLER_FOUND // catch!
-        }
-        else { // cleanup phase
-            unsafe {
-                 __gcc_personality_v0(version, actions, exception_class, ue_header,
-                                      context)
-            }
-        }
-    }
-}
-
-// ARM EHABI uses a slightly different personality routine signature,
-// but otherwise works the same.
-#[cfg(target_arch = "arm", not(test))]
-#[allow(visible_private_types)]
-pub mod eabi {
-    use uw = rt::libunwind;
-    use libc::c_int;
-
-    extern "C" {
-        fn __gcc_personality_v0(state: uw::_Unwind_State,
-                                ue_header: *uw::_Unwind_Exception,
-                                context: *uw::_Unwind_Context)
-            -> uw::_Unwind_Reason_Code;
-    }
-
-    #[lang="eh_personality"]
-    extern "C" fn eh_personality(
-        state: uw::_Unwind_State,
-        ue_header: *uw::_Unwind_Exception,
-        context: *uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        unsafe {
-            __gcc_personality_v0(state, ue_header, context)
-        }
-    }
-
-    #[no_mangle] // referenced from rust_try.ll
-    pub extern "C" fn rust_eh_personality_catch(
-        state: uw::_Unwind_State,
-        ue_header: *uw::_Unwind_Exception,
-        context: *uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        if (state as c_int & uw::_US_ACTION_MASK as c_int)
-                           == uw::_US_VIRTUAL_UNWIND_FRAME as c_int { // search phase
-            uw::_URC_HANDLER_FOUND // catch!
-        }
-        else { // cleanup phase
-            unsafe {
-                 __gcc_personality_v0(state, ue_header, context)
-            }
-        }
-    }
-}
-
-// Entry point of failure from the libcore crate
-#[cfg(not(test))]
-#[lang = "begin_unwind"]
-pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
-                                file: &'static str, line: uint) -> ! {
-    begin_unwind_fmt(msg, file, line)
-}
-
-/// The entry point for unwinding with a formatted message.
-///
-/// This is designed to reduce the amount of code required at the call
-/// site as much as possible (so that `fail!()` has as low an impact
-/// on (e.g.) the inlining of other functions as possible), by moving
-/// the actual formatting into this shared place.
-#[inline(never)] #[cold]
-pub fn begin_unwind_fmt(msg: &fmt::Arguments, file: &'static str,
-                        line: uint) -> ! {
-    // We do two allocations here, unfortunately. But (a) they're
-    // required with the current scheme, and (b) we don't handle
-    // failure + OOM properly anyway (see comment in begin_unwind
-    // below).
-    begin_unwind_inner(box fmt::format(msg), file, line)
-}
-
-/// This is the entry point of unwinding for fail!() and assert!().
-#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
-pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
-    // Note that this should be the only allocation performed in this code path.
-    // Currently this means that fail!() on OOM will invoke this code path,
-    // but then again we're not really ready for failing on OOM anyway. If
-    // we do start doing this, then we should propagate this allocation to
-    // be performed in the parent of this task instead of the task that's
-    // failing.
-
-    // see below for why we do the `Any` coercion here.
-    begin_unwind_inner(box msg, file, line)
-}
-
-
-/// The core of the unwinding.
-///
-/// This is non-generic to avoid instantiation bloat in other crates
-/// (which makes compilation of small crates noticably slower). (Note:
-/// we need the `Any` object anyway, we're not just creating it to
-/// avoid being generic.)
-///
-/// Do this split took the LLVM IR line counts of `fn main() { fail!()
-/// }` from ~1900/3700 (-O/no opts) to 180/590.
-#[inline(never)] #[cold] // this is the slow path, please never inline this
-fn begin_unwind_inner(msg: Box<Any:Send>,
-                      file: &'static str,
-                      line: uint) -> ! {
-    // First up, print the message that we're failing
-    print_failure(msg, file, line);
-
-    let opt_task: Option<Box<Task>> = Local::try_take();
-    match opt_task {
-        Some(mut task) => {
-            // Now that we've printed why we're failing, do a check
-            // to make sure that we're not double failing.
-            //
-            // If a task fails while it's already unwinding then we
-            // have limited options. Currently our preference is to
-            // just abort. In the future we may consider resuming
-            // unwinding or otherwise exiting the task cleanly.
-            if task.unwinder.unwinding {
-                rterrln!("task failed during unwinding. aborting.");
-
-                // Don't print the backtrace twice (it would have already been
-                // printed if logging was enabled).
-                if !backtrace::log_enabled() {
-                    let mut err = ::rt::util::Stderr;
-                    let _err = backtrace::write(&mut err);
-                }
-                unsafe { intrinsics::abort() }
-            }
-
-            // Finally, we've printed our failure and figured out we're not in a
-            // double failure, so flag that we've started to unwind and then
-            // actually unwind.  Be sure that the task is in TLS so destructors
-            // can do fun things like I/O.
-            task.unwinder.unwinding = true;
-            Local::put(task);
-        }
-        None => {}
-    }
-    rust_fail(msg)
-}
-
-/// Given a failure message and the location that it occurred, prints the
-/// message to the local task's appropriate stream.
-///
-/// This function currently handles three cases:
-///
-///     - There is no local task available. In this case the error is printed to
-///       stderr.
-///     - There is a local task available, but it does not have a stderr handle.
-///       In this case the message is also printed to stderr.
-///     - There is a local task available, and it has a stderr handle. The
-///       message is printed to the handle given in this case.
-fn print_failure(msg: &Any:Send, file: &str, line: uint) {
-    let msg = match msg.as_ref::<&'static str>() {
-        Some(s) => *s,
-        None => match msg.as_ref::<String>() {
-            Some(s) => s.as_slice(),
-            None => "Box<Any>",
-        }
-    };
-
-    // It is assumed that all reasonable rust code will have a local task at
-    // all times. This means that this `try_take` will succeed almost all of
-    // the time. There are border cases, however, when the runtime has
-    // *almost* set up the local task, but hasn't quite gotten there yet. In
-    // order to get some better diagnostics, we print on failure and
-    // immediately abort the whole process if there is no local task
-    // available.
-    let mut task: Box<Task> = match Local::try_take() {
-        Some(t) => t,
-        None => {
-            rterrln!("failed at '{}', {}:{}", msg, file, line);
-            if backtrace::log_enabled() {
-                let mut err = ::rt::util::Stderr;
-                let _err = backtrace::write(&mut err);
-            } else {
-                rterrln!("run with `RUST_BACKTRACE=1` to see a backtrace");
-            }
-            return
-        }
-    };
-
-    // See comments in io::stdio::with_task_stdout as to why we have to be
-    // careful when using an arbitrary I/O handle from the task. We
-    // essentially need to dance to make sure when a task is in TLS when
-    // running user code.
-    let name = task.name.take();
-    {
-        let n = name.as_ref().map(|n| n.as_slice()).unwrap_or("<unnamed>");
-
-        match task.stderr.take() {
-            Some(mut stderr) => {
-                Local::put(task);
-                // FIXME: what to do when the task printing fails?
-                let _err = write!(stderr,
-                                  "task '{}' failed at '{}', {}:{}\n",
-                                  n, msg, file, line);
-                if backtrace::log_enabled() {
-                    let _err = backtrace::write(stderr);
-                }
-                task = Local::take();
-
-                match mem::replace(&mut task.stderr, Some(stderr)) {
-                    Some(prev) => {
-                        Local::put(task);
-                        drop(prev);
-                        task = Local::take();
-                    }
-                    None => {}
-                }
-            }
-            None => {
-                rterrln!("task '{}' failed at '{}', {}:{}", n, msg, file, line);
-                if backtrace::log_enabled() {
-                    let mut err = ::rt::util::Stderr;
-                    let _err = backtrace::write(&mut err);
-                }
-            }
-        }
-    }
-    task.name = name;
-    Local::put(task);
-}
diff --git a/src/libstd/rt/util.rs b/src/libstd/rt/util.rs
index 103fbdc0bc9..670d4aa2061 100644
--- a/src/libstd/rt/util.rs
+++ b/src/libstd/rt/util.rs
@@ -8,23 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use container::Container;
-use fmt;
 use from_str::FromStr;
-use io::IoResult;
-use io;
-use iter::Iterator;
-use libc;
+use from_str::from_str;
 use libc::uintptr_t;
+use libc;
 use option::{Some, None, Option};
 use os;
-use result::Ok;
-use str::{Str, StrSlice};
-use slice::ImmutableVector;
-
-// Indicates whether we should perform expensive sanity checks, including rtassert!
-// FIXME: Once the runtime matures remove the `true` below to turn off rtassert, etc.
-pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);
+use str::Str;
+use sync::atomics;
 
 /// Get the number of cores available
 pub fn num_cpus() -> uint {
@@ -37,6 +28,17 @@ pub fn num_cpus() -> uint {
     }
 }
 
+/// Dynamically inquire about whether we're running under V.
+/// You should usually not use this unless your test definitely
+/// can't run correctly un-altered. Valgrind is there to help
+/// you notice weirdness in normal, un-doctored code paths!
+pub fn running_on_valgrind() -> bool {
+    extern {
+        fn rust_running_on_valgrind() -> uintptr_t;
+    }
+    unsafe { rust_running_on_valgrind() != 0 }
+}
+
 /// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
 /// wired into it; this is a hard limit and requires rebuilding valgrind if you
 /// want to go beyond it. Normally this is not a problem, but in some tests, we
@@ -50,6 +52,20 @@ pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
     (cfg!(target_os="macos")) && running_on_valgrind()
 }
 
+pub fn min_stack() -> uint {
+    static mut MIN: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
+    match unsafe { MIN.load(atomics::SeqCst) } {
+        0 => {}
+        n => return n - 1,
+    }
+    let amt = os::getenv("RUST_MIN_STACK").and_then(|s| from_str(s.as_slice()));
+    let amt = amt.unwrap_or(2 * 1024 * 1024);
+    // 0 is our sentinel value, so ensure that we'll never see 0 after
+    // initialization has run
+    unsafe { MIN.store(amt + 1, atomics::SeqCst); }
+    return amt;
+}
+
 /// Get's the number of scheduler threads requested by the environment
 /// either `RUST_THREADS` or `num_cpus`.
 pub fn default_sched_threads() -> uint {
@@ -58,7 +74,7 @@ pub fn default_sched_threads() -> uint {
             let opt_n: Option<uint> = FromStr::from_str(nstr.as_slice());
             match opt_n {
                 Some(n) if n > 0 => n,
-                _ => rtabort!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
+                _ => fail!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
             }
         }
         None => {
@@ -70,107 +86,3 @@ pub fn default_sched_threads() -> uint {
         }
     }
 }
-
-pub struct Stdio(libc::c_int);
-
-pub static Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
-pub static Stderr: Stdio = Stdio(libc::STDERR_FILENO);
-
-impl io::Writer for Stdio {
-    fn write(&mut self, data: &[u8]) -> IoResult<()> {
-        #[cfg(unix)]
-        type WriteLen = libc::size_t;
-        #[cfg(windows)]
-        type WriteLen = libc::c_uint;
-        unsafe {
-            let Stdio(fd) = *self;
-            libc::write(fd,
-                        data.as_ptr() as *libc::c_void,
-                        data.len() as WriteLen);
-        }
-        Ok(()) // yes, we're lying
-    }
-}
-
-pub fn dumb_println(args: &fmt::Arguments) {
-    use io::Writer;
-    let mut w = Stderr;
-    let _ = writeln!(&mut w, "{}", args);
-}
-
-pub fn abort(msg: &str) -> ! {
-    let msg = if !msg.is_empty() { msg } else { "aborted" };
-    let hash = msg.chars().fold(0, |accum, val| accum + (val as uint) );
-    let quote = match hash % 10 {
-        0 => "
-It was from the artists and poets that the pertinent answers came, and I
-know that panic would have broken loose had they been able to compare notes.
-As it was, lacking their original letters, I half suspected the compiler of
-having asked leading questions, or of having edited the correspondence in
-corroboration of what he had latently resolved to see.",
-        1 => "
-There are not many persons who know what wonders are opened to them in the
-stories and visions of their youth; for when as children we listen and dream,
-we think but half-formed thoughts, and when as men we try to remember, we are
-dulled and prosaic with the poison of life. But some of us awake in the night
-with strange phantasms of enchanted hills and gardens, of fountains that sing
-in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
-down to sleeping cities of bronze and stone, and of shadowy companies of heroes
-that ride caparisoned white horses along the edges of thick forests; and then
-we know that we have looked back through the ivory gates into that world of
-wonder which was ours before we were wise and unhappy.",
-        2 => "
-Instead of the poems I had hoped for, there came only a shuddering blackness
-and ineffable loneliness; and I saw at last a fearful truth which no one had
-ever dared to breathe before — the unwhisperable secret of secrets — The fact
-that this city of stone and stridor is not a sentient perpetuation of Old New
-York as London is of Old London and Paris of Old Paris, but that it is in fact
-quite dead, its sprawling body imperfectly embalmed and infested with queer
-animate things which have nothing to do with it as it was in life.",
-        3 => "
-The ocean ate the last of the land and poured into the smoking gulf, thereby
-giving up all it had ever conquered. From the new-flooded lands it flowed
-again, uncovering death and decay; and from its ancient and immemorial bed it
-trickled loathsomely, uncovering nighted secrets of the years when Time was
-young and the gods unborn. Above the waves rose weedy remembered spires. The
-moon laid pale lilies of light on dead London, and Paris stood up from its damp
-grave to be sanctified with star-dust. Then rose spires and monoliths that were
-weedy but not remembered; terrible spires and monoliths of lands that men never
-knew were lands...",
-        4 => "
-There was a night when winds from unknown spaces whirled us irresistibly into
-limitless vacuum beyond all thought and entity. Perceptions of the most
-maddeningly untransmissible sort thronged upon us; perceptions of infinity
-which at the time convulsed us with joy, yet which are now partly lost to my
-memory and partly incapable of presentation to others.",
-        _ => "You've met with a terrible fate, haven't you?"
-    };
-    ::alloc::util::make_stdlib_link_work(); // see comments in liballoc
-    rterrln!("{}", "");
-    rterrln!("{}", quote);
-    rterrln!("{}", "");
-    rterrln!("fatal runtime error: {}", msg);
-
-    {
-        let mut err = Stderr;
-        let _err = ::rt::backtrace::write(&mut err);
-    }
-    abort();
-
-    fn abort() -> ! {
-        use intrinsics;
-        unsafe { intrinsics::abort() }
-    }
-}
-
-/// Dynamically inquire about whether we're running under V.
-/// You should usually not use this unless your test definitely
-/// can't run correctly un-altered. Valgrind is there to help
-/// you notice weirdness in normal, un-doctored code paths!
-pub fn running_on_valgrind() -> bool {
-    unsafe { rust_running_on_valgrind() != 0 }
-}
-
-extern {
-    fn rust_running_on_valgrind() -> uintptr_t;
-}
diff --git a/src/libstd/unstable/mutex.rs b/src/libstd/unstable/mutex.rs
deleted file mode 100644
index 4e51e714777..00000000000
--- a/src/libstd/unstable/mutex.rs
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright 2013-2014 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.
-
-//! A native mutex and condition variable type.
-//!
-//! This module contains bindings to the platform's native mutex/condition
-//! variable primitives. It provides two types: `StaticNativeMutex`, which can
-//! be statically initialized via the `NATIVE_MUTEX_INIT` value, and a simple
-//! wrapper `NativeMutex` that has a destructor to clean up after itself. These
-//! objects serve as both mutexes and condition variables simultaneously.
-//!
-//! The static lock is lazily initialized, but it can only be unsafely
-//! destroyed. A statically initialized lock doesn't necessarily have a time at
-//! which it can get deallocated. For this reason, there is no `Drop`
-//! implementation of the static mutex, but rather the `destroy()` method must
-//! be invoked manually if destruction of the mutex is desired.
-//!
-//! The non-static `NativeMutex` type does have a destructor, but cannot be
-//! statically initialized.
-//!
-//! It is not recommended to use this type for idiomatic rust use. These types
-//! are appropriate where no other options are available, but other rust
-//! concurrency primitives should be used before them: the `sync` crate defines
-//! `StaticMutex` and `Mutex` types.
-//!
-//! # Example
-//!
-//! ```rust
-//! use std::unstable::mutex::{NativeMutex, StaticNativeMutex, NATIVE_MUTEX_INIT};
-//!
-//! // Use a statically initialized mutex
-//! static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-//!
-//! unsafe {
-//!     let _guard = LOCK.lock();
-//! } // automatically unlocked here
-//!
-//! // Use a normally initialized mutex
-//! unsafe {
-//!     let mut lock = NativeMutex::new();
-//!
-//!     {
-//!         let _guard = lock.lock();
-//!     } // unlocked here
-//!
-//!     // sometimes the RAII guard isn't appropriate
-//!     lock.lock_noguard();
-//!     lock.unlock_noguard();
-//! } // `lock` is deallocated here
-//! ```
-
-#![allow(non_camel_case_types)]
-
-use option::{Option, None, Some};
-use ops::Drop;
-
-/// A native mutex suitable for storing in statics (that is, it has
-/// the `destroy` method rather than a destructor).
-///
-/// Prefer the `NativeMutex` type where possible, since that does not
-/// require manual deallocation.
-pub struct StaticNativeMutex {
-    inner: imp::Mutex,
-}
-
-/// A native mutex with a destructor for clean-up.
-///
-/// See `StaticNativeMutex` for a version that is suitable for storing in
-/// statics.
-pub struct NativeMutex {
-    inner: StaticNativeMutex
-}
-
-/// Automatically unlocks the mutex that it was created from on
-/// destruction.
-///
-/// Using this makes lock-based code resilient to unwinding/task
-/// failure, because the lock will be automatically unlocked even
-/// then.
-#[must_use]
-pub struct LockGuard<'a> {
-    lock: &'a StaticNativeMutex
-}
-
-pub static NATIVE_MUTEX_INIT: StaticNativeMutex = StaticNativeMutex {
-    inner: imp::MUTEX_INIT,
-};
-
-impl StaticNativeMutex {
-    /// Creates a new mutex.
-    ///
-    /// Note that a mutex created in this way needs to be explicit
-    /// freed with a call to `destroy` or it will leak.
-    /// Also it is important to avoid locking until mutex has stopped moving
-    pub unsafe fn new() -> StaticNativeMutex {
-        StaticNativeMutex { inner: imp::Mutex::new() }
-    }
-
-    /// Acquires this lock. This assumes that the current thread does not
-    /// already hold the lock.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-    /// static mut LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
-    /// unsafe {
-    ///     let _guard = LOCK.lock();
-    ///     // critical section...
-    /// } // automatically unlocked in `_guard`'s destructor
-    /// ```
-    pub unsafe fn lock<'a>(&'a self) -> LockGuard<'a> {
-        self.inner.lock();
-
-        LockGuard { lock: self }
-    }
-
-    /// Attempts to acquire the lock. The value returned is `Some` if
-    /// the attempt succeeded.
-    pub unsafe fn trylock<'a>(&'a self) -> Option<LockGuard<'a>> {
-        if self.inner.trylock() {
-            Some(LockGuard { lock: self })
-        } else {
-            None
-        }
-    }
-
-    /// Acquire the lock without creating a `LockGuard`.
-    ///
-    /// These needs to be paired with a call to `.unlock_noguard`. Prefer using
-    /// `.lock`.
-    pub unsafe fn lock_noguard(&self) { self.inner.lock() }
-
-    /// Attempts to acquire the lock without creating a
-    /// `LockGuard`. The value returned is whether the lock was
-    /// acquired or not.
-    ///
-    /// If `true` is returned, this needs to be paired with a call to
-    /// `.unlock_noguard`. Prefer using `.trylock`.
-    pub unsafe fn trylock_noguard(&self) -> bool {
-        self.inner.trylock()
-    }
-
-    /// Unlocks the lock. This assumes that the current thread already holds the
-    /// lock.
-    pub unsafe fn unlock_noguard(&self) { self.inner.unlock() }
-
-    /// Block on the internal condition variable.
-    ///
-    /// This function assumes that the lock is already held. Prefer
-    /// using `LockGuard.wait` since that guarantees that the lock is
-    /// held.
-    pub unsafe fn wait_noguard(&self) { self.inner.wait() }
-
-    /// Signals a thread in `wait` to wake up
-    pub unsafe fn signal_noguard(&self) { self.inner.signal() }
-
-    /// This function is especially unsafe because there are no guarantees made
-    /// that no other thread is currently holding the lock or waiting on the
-    /// condition variable contained inside.
-    pub unsafe fn destroy(&self) { self.inner.destroy() }
-}
-
-impl NativeMutex {
-    /// Creates a new mutex.
-    ///
-    /// The user must be careful to ensure the mutex is not locked when its is
-    /// being destroyed.
-    /// Also it is important to avoid locking until mutex has stopped moving
-    pub unsafe fn new() -> NativeMutex {
-        NativeMutex { inner: StaticNativeMutex::new() }
-    }
-
-    /// Acquires this lock. This assumes that the current thread does not
-    /// already hold the lock.
-    ///
-    /// # Example
-    /// ```rust
-    /// use std::unstable::mutex::NativeMutex;
-    /// unsafe {
-    ///     let mut lock = NativeMutex::new();
-    ///
-    ///     {
-    ///         let _guard = lock.lock();
-    ///         // critical section...
-    ///     } // automatically unlocked in `_guard`'s destructor
-    /// }
-    /// ```
-    pub unsafe fn lock<'a>(&'a self) -> LockGuard<'a> {
-        self.inner.lock()
-    }
-
-    /// Attempts to acquire the lock. The value returned is `Some` if
-    /// the attempt succeeded.
-    pub unsafe fn trylock<'a>(&'a self) -> Option<LockGuard<'a>> {
-        self.inner.trylock()
-    }
-
-    /// Acquire the lock without creating a `LockGuard`.
-    ///
-    /// These needs to be paired with a call to `.unlock_noguard`. Prefer using
-    /// `.lock`.
-    pub unsafe fn lock_noguard(&self) { self.inner.lock_noguard() }
-
-    /// Attempts to acquire the lock without creating a
-    /// `LockGuard`. The value returned is whether the lock was
-    /// acquired or not.
-    ///
-    /// If `true` is returned, this needs to be paired with a call to
-    /// `.unlock_noguard`. Prefer using `.trylock`.
-    pub unsafe fn trylock_noguard(&self) -> bool {
-        self.inner.trylock_noguard()
-    }
-
-    /// Unlocks the lock. This assumes that the current thread already holds the
-    /// lock.
-    pub unsafe fn unlock_noguard(&self) { self.inner.unlock_noguard() }
-
-    /// Block on the internal condition variable.
-    ///
-    /// This function assumes that the lock is already held. Prefer
-    /// using `LockGuard.wait` since that guarantees that the lock is
-    /// held.
-    pub unsafe fn wait_noguard(&self) { self.inner.wait_noguard() }
-
-    /// Signals a thread in `wait` to wake up
-    pub unsafe fn signal_noguard(&self) { self.inner.signal_noguard() }
-}
-
-impl Drop for NativeMutex {
-    fn drop(&mut self) {
-        unsafe {self.inner.destroy()}
-    }
-}
-
-impl<'a> LockGuard<'a> {
-    /// Block on the internal condition variable.
-    pub unsafe fn wait(&self) {
-        self.lock.wait_noguard()
-    }
-
-    /// Signals a thread in `wait` to wake up.
-    pub unsafe fn signal(&self) {
-        self.lock.signal_noguard()
-    }
-}
-
-#[unsafe_destructor]
-impl<'a> Drop for LockGuard<'a> {
-    fn drop(&mut self) {
-        unsafe {self.lock.unlock_noguard()}
-    }
-}
-
-#[cfg(unix)]
-mod imp {
-    use libc;
-    use self::os::{PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER,
-                   pthread_mutex_t, pthread_cond_t};
-    use ty::Unsafe;
-    use kinds::marker;
-
-    type pthread_mutexattr_t = libc::c_void;
-    type pthread_condattr_t = libc::c_void;
-
-    #[cfg(target_os = "freebsd")]
-    mod os {
-        use libc;
-
-        pub type pthread_mutex_t = *libc::c_void;
-        pub type pthread_cond_t = *libc::c_void;
-
-        pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t =
-            0 as pthread_mutex_t;
-        pub static PTHREAD_COND_INITIALIZER: pthread_cond_t =
-            0 as pthread_cond_t;
-    }
-
-    #[cfg(target_os = "macos")]
-    mod os {
-        use libc;
-
-        #[cfg(target_arch = "x86_64")]
-        static __PTHREAD_MUTEX_SIZE__: uint = 56;
-        #[cfg(target_arch = "x86_64")]
-        static __PTHREAD_COND_SIZE__: uint = 40;
-        #[cfg(target_arch = "x86")]
-        static __PTHREAD_MUTEX_SIZE__: uint = 40;
-        #[cfg(target_arch = "x86")]
-        static __PTHREAD_COND_SIZE__: uint = 24;
-
-        static _PTHREAD_MUTEX_SIG_init: libc::c_long = 0x32AAABA7;
-        static _PTHREAD_COND_SIG_init: libc::c_long = 0x3CB0B1BB;
-
-        pub struct pthread_mutex_t {
-            __sig: libc::c_long,
-            __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
-        }
-        pub struct pthread_cond_t {
-            __sig: libc::c_long,
-            __opaque: [u8, ..__PTHREAD_COND_SIZE__],
-        }
-
-        pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
-            __sig: _PTHREAD_MUTEX_SIG_init,
-            __opaque: [0, ..__PTHREAD_MUTEX_SIZE__],
-        };
-        pub static PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
-            __sig: _PTHREAD_COND_SIG_init,
-            __opaque: [0, ..__PTHREAD_COND_SIZE__],
-        };
-    }
-
-    #[cfg(target_os = "linux")]
-    mod os {
-        use libc;
-
-        // minus 8 because we have an 'align' field
-        #[cfg(target_arch = "x86_64")]
-        static __SIZEOF_PTHREAD_MUTEX_T: uint = 40 - 8;
-        #[cfg(target_arch = "x86")]
-        static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
-        #[cfg(target_arch = "arm")]
-        static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
-        #[cfg(target_arch = "mips")]
-        static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
-        #[cfg(target_arch = "x86_64")]
-        static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
-        #[cfg(target_arch = "x86")]
-        static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
-        #[cfg(target_arch = "arm")]
-        static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
-        #[cfg(target_arch = "mips")]
-        static __SIZEOF_PTHREAD_COND_T: uint = 48 - 8;
-
-        pub struct pthread_mutex_t {
-            __align: libc::c_longlong,
-            size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
-        }
-        pub struct pthread_cond_t {
-            __align: libc::c_longlong,
-            size: [u8, ..__SIZEOF_PTHREAD_COND_T],
-        }
-
-        pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
-            __align: 0,
-            size: [0, ..__SIZEOF_PTHREAD_MUTEX_T],
-        };
-        pub static PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
-            __align: 0,
-            size: [0, ..__SIZEOF_PTHREAD_COND_T],
-        };
-    }
-    #[cfg(target_os = "android")]
-    mod os {
-        use libc;
-
-        pub struct pthread_mutex_t { value: libc::c_int }
-        pub struct pthread_cond_t { value: libc::c_int }
-
-        pub static PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
-            value: 0,
-        };
-        pub static PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
-            value: 0,
-        };
-    }
-
-    pub struct Mutex {
-        lock: Unsafe<pthread_mutex_t>,
-        cond: Unsafe<pthread_cond_t>,
-    }
-
-    pub static MUTEX_INIT: Mutex = Mutex {
-        lock: Unsafe {
-            value: PTHREAD_MUTEX_INITIALIZER,
-            marker1: marker::InvariantType,
-        },
-        cond: Unsafe {
-            value: PTHREAD_COND_INITIALIZER,
-            marker1: marker::InvariantType,
-        },
-    };
-
-    impl Mutex {
-        pub unsafe fn new() -> Mutex {
-            // As mutex might be moved and address is changing it
-            // is better to avoid initialization of potentially
-            // opaque OS data before it landed
-            let m = Mutex {
-                lock: Unsafe::new(PTHREAD_MUTEX_INITIALIZER),
-                cond: Unsafe::new(PTHREAD_COND_INITIALIZER),
-            };
-
-            return m;
-        }
-
-        pub unsafe fn lock(&self) { pthread_mutex_lock(self.lock.get()); }
-        pub unsafe fn unlock(&self) { pthread_mutex_unlock(self.lock.get()); }
-        pub unsafe fn signal(&self) { pthread_cond_signal(self.cond.get()); }
-        pub unsafe fn wait(&self) {
-            pthread_cond_wait(self.cond.get(), self.lock.get());
-        }
-        pub unsafe fn trylock(&self) -> bool {
-            pthread_mutex_trylock(self.lock.get()) == 0
-        }
-        pub unsafe fn destroy(&self) {
-            pthread_mutex_destroy(self.lock.get());
-            pthread_cond_destroy(self.cond.get());
-        }
-    }
-
-    extern {
-        fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> libc::c_int;
-        fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> libc::c_int;
-        fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> libc::c_int;
-        fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> libc::c_int;
-        fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> libc::c_int;
-
-        fn pthread_cond_wait(cond: *mut pthread_cond_t,
-                             lock: *mut pthread_mutex_t) -> libc::c_int;
-        fn pthread_cond_signal(cond: *mut pthread_cond_t) -> libc::c_int;
-    }
-}
-
-#[cfg(windows)]
-mod imp {
-    use rt::libc_heap::malloc_raw;
-    use libc::{HANDLE, BOOL, LPSECURITY_ATTRIBUTES, c_void, DWORD, LPCSTR};
-    use libc;
-    use ptr;
-    use sync::atomics;
-
-    type LPCRITICAL_SECTION = *mut c_void;
-    static SPIN_COUNT: DWORD = 4000;
-    #[cfg(target_arch = "x86")]
-    static CRIT_SECTION_SIZE: uint = 24;
-    #[cfg(target_arch = "x86_64")]
-    static CRIT_SECTION_SIZE: uint = 40;
-
-    pub struct Mutex {
-        // pointers for the lock/cond handles, atomically updated
-        lock: atomics::AtomicUint,
-        cond: atomics::AtomicUint,
-    }
-
-    pub static MUTEX_INIT: Mutex = Mutex {
-        lock: atomics::INIT_ATOMIC_UINT,
-        cond: atomics::INIT_ATOMIC_UINT,
-    };
-
-    impl Mutex {
-        pub unsafe fn new() -> Mutex {
-            Mutex {
-                lock: atomics::AtomicUint::new(init_lock()),
-                cond: atomics::AtomicUint::new(init_cond()),
-            }
-        }
-        pub unsafe fn lock(&self) {
-            EnterCriticalSection(self.getlock() as LPCRITICAL_SECTION)
-        }
-        pub unsafe fn trylock(&self) -> bool {
-            TryEnterCriticalSection(self.getlock() as LPCRITICAL_SECTION) != 0
-        }
-        pub unsafe fn unlock(&self) {
-            LeaveCriticalSection(self.getlock() as LPCRITICAL_SECTION)
-        }
-
-        pub unsafe fn wait(&self) {
-            self.unlock();
-            WaitForSingleObject(self.getcond() as HANDLE, libc::INFINITE);
-            self.lock();
-        }
-
-        pub unsafe fn signal(&self) {
-            assert!(SetEvent(self.getcond() as HANDLE) != 0);
-        }
-
-        /// This function is especially unsafe because there are no guarantees made
-        /// that no other thread is currently holding the lock or waiting on the
-        /// condition variable contained inside.
-        pub unsafe fn destroy(&self) {
-            let lock = self.lock.swap(0, atomics::SeqCst);
-            let cond = self.cond.swap(0, atomics::SeqCst);
-            if lock != 0 { free_lock(lock) }
-            if cond != 0 { free_cond(cond) }
-        }
-
-        unsafe fn getlock(&self) -> *mut c_void {
-            match self.lock.load(atomics::SeqCst) {
-                0 => {}
-                n => return n as *mut c_void
-            }
-            let lock = init_lock();
-            match self.lock.compare_and_swap(0, lock, atomics::SeqCst) {
-                0 => return lock as *mut c_void,
-                _ => {}
-            }
-            free_lock(lock);
-            return self.lock.load(atomics::SeqCst) as *mut c_void;
-        }
-
-        unsafe fn getcond(&self) -> *mut c_void {
-            match self.cond.load(atomics::SeqCst) {
-                0 => {}
-                n => return n as *mut c_void
-            }
-            let cond = init_cond();
-            match self.cond.compare_and_swap(0, cond, atomics::SeqCst) {
-                0 => return cond as *mut c_void,
-                _ => {}
-            }
-            free_cond(cond);
-            return self.cond.load(atomics::SeqCst) as *mut c_void;
-        }
-    }
-
-    pub unsafe fn init_lock() -> uint {
-        let block = malloc_raw(CRIT_SECTION_SIZE as uint) as *mut c_void;
-        InitializeCriticalSectionAndSpinCount(block, SPIN_COUNT);
-        return block as uint;
-    }
-
-    pub unsafe fn init_cond() -> uint {
-        return CreateEventA(ptr::mut_null(), libc::FALSE, libc::FALSE,
-                            ptr::null()) as uint;
-    }
-
-    pub unsafe fn free_lock(h: uint) {
-        DeleteCriticalSection(h as LPCRITICAL_SECTION);
-        libc::free(h as *mut c_void);
-    }
-
-    pub unsafe fn free_cond(h: uint) {
-        let block = h as HANDLE;
-        libc::CloseHandle(block);
-    }
-
-    #[allow(non_snake_case_functions)]
-    extern "system" {
-        fn CreateEventA(lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
-                        bManualReset: BOOL,
-                        bInitialState: BOOL,
-                        lpName: LPCSTR) -> HANDLE;
-        fn InitializeCriticalSectionAndSpinCount(
-                        lpCriticalSection: LPCRITICAL_SECTION,
-                        dwSpinCount: DWORD) -> BOOL;
-        fn DeleteCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
-        fn EnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
-        fn LeaveCriticalSection(lpCriticalSection: LPCRITICAL_SECTION);
-        fn TryEnterCriticalSection(lpCriticalSection: LPCRITICAL_SECTION) -> BOOL;
-        fn SetEvent(hEvent: HANDLE) -> BOOL;
-        fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use prelude::*;
-
-    use mem::drop;
-    use super::{StaticNativeMutex, NATIVE_MUTEX_INIT};
-    use rt::thread::Thread;
-
-    #[test]
-    fn smoke_lock() {
-        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        unsafe {
-            let _guard = lock.lock();
-        }
-    }
-
-    #[test]
-    fn smoke_cond() {
-        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        unsafe {
-            let guard = lock.lock();
-            let t = Thread::start(proc() {
-                let guard = lock.lock();
-                guard.signal();
-            });
-            guard.wait();
-            drop(guard);
-
-            t.join();
-        }
-    }
-
-    #[test]
-    fn smoke_lock_noguard() {
-        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        unsafe {
-            lock.lock_noguard();
-            lock.unlock_noguard();
-        }
-    }
-
-    #[test]
-    fn smoke_cond_noguard() {
-        static mut lock: StaticNativeMutex = NATIVE_MUTEX_INIT;
-        unsafe {
-            lock.lock_noguard();
-            let t = Thread::start(proc() {
-                lock.lock_noguard();
-                lock.signal_noguard();
-                lock.unlock_noguard();
-            });
-            lock.wait_noguard();
-            lock.unlock_noguard();
-
-            t.join();
-        }
-    }
-
-    #[test]
-    fn destroy_immediately() {
-        unsafe {
-            let m = StaticNativeMutex::new();
-            m.destroy();
-        }
-    }
-}
diff --git a/src/libstd/unstable/sync.rs b/src/libstd/unstable/sync.rs
deleted file mode 100644
index f0f7e40ce09..00000000000
--- a/src/libstd/unstable/sync.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2013 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 alloc::arc::Arc;
-
-use clone::Clone;
-use kinds::Send;
-use ty::Unsafe;
-use unstable::mutex::NativeMutex;
-
-struct ExData<T> {
-    lock: NativeMutex,
-    failed: bool,
-    data: T,
-}
-
-/**
- * An arc over mutable data that is protected by a lock. For library use only.
- *
- * # Safety note
- *
- * This uses a pthread mutex, not one that's aware of the userspace scheduler.
- * The user of an Exclusive must be careful not to invoke any functions that may
- * reschedule the task while holding the lock, or deadlock may result. If you
- * need to block or deschedule while accessing shared state, use extra::sync::RWArc.
- */
-pub struct Exclusive<T> {
-    x: Arc<Unsafe<ExData<T>>>
-}
-
-impl<T:Send> Clone for Exclusive<T> {
-    // Duplicate an Exclusive Arc, as std::arc::clone.
-    fn clone(&self) -> Exclusive<T> {
-        Exclusive { x: self.x.clone() }
-    }
-}
-
-impl<T:Send> Exclusive<T> {
-    pub fn new(user_data: T) -> Exclusive<T> {
-        let data = ExData {
-            lock: unsafe {NativeMutex::new()},
-            failed: false,
-            data: user_data
-        };
-        Exclusive {
-            x: Arc::new(Unsafe::new(data))
-        }
-    }
-
-    // Exactly like sync::MutexArc.access(). Same reason for being
-    // unsafe.
-    //
-    // Currently, scheduling operations (i.e., descheduling, receiving on a pipe,
-    // accessing the provided condition variable) are prohibited while inside
-    // the Exclusive. Supporting that is a work in progress.
-    #[inline]
-    pub unsafe fn with<U>(&self, f: |x: &mut T| -> U) -> U {
-        let rec = self.x.get();
-        let _l = (*rec).lock.lock();
-        if (*rec).failed {
-            fail!("Poisoned Exclusive::new - another task failed inside!");
-        }
-        (*rec).failed = true;
-        let result = f(&mut (*rec).data);
-        (*rec).failed = false;
-        result
-    }
-
-    #[inline]
-    pub unsafe fn with_imm<U>(&self, f: |x: &T| -> U) -> U {
-        self.with(|x| f(x))
-    }
-
-    #[inline]
-    pub unsafe fn hold_and_signal(&self, f: |x: &mut T|) {
-        let rec = self.x.get();
-        let guard = (*rec).lock.lock();
-        if (*rec).failed {
-            fail!("Poisoned Exclusive::new - another task failed inside!");
-        }
-        (*rec).failed = true;
-        f(&mut (*rec).data);
-        (*rec).failed = false;
-        guard.signal();
-    }
-
-    #[inline]
-    pub unsafe fn hold_and_wait(&self, f: |x: &T| -> bool) {
-        let rec = self.x.get();
-        let l = (*rec).lock.lock();
-        if (*rec).failed {
-            fail!("Poisoned Exclusive::new - another task failed inside!");
-        }
-        (*rec).failed = true;
-        let result = f(&(*rec).data);
-        (*rec).failed = false;
-        if result {
-            l.wait();
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use option::*;
-    use prelude::*;
-    use super::Exclusive;
-    use task;
-
-    #[test]
-    fn exclusive_new_arc() {
-        unsafe {
-            let mut futures = Vec::new();
-
-            let num_tasks = 10;
-            let count = 10;
-
-            let total = Exclusive::new(box 0);
-
-            for _ in range(0u, num_tasks) {
-                let total = total.clone();
-                let (tx, rx) = channel();
-                futures.push(rx);
-
-                task::spawn(proc() {
-                    for _ in range(0u, count) {
-                        total.with(|count| **count += 1);
-                    }
-                    tx.send(());
-                });
-            };
-
-            for f in futures.mut_iter() { f.recv() }
-
-            total.with(|total| assert!(**total == num_tasks * count));
-        }
-    }
-
-    #[test] #[should_fail]
-    fn exclusive_new_poison() {
-        unsafe {
-            // Tests that if one task fails inside of an Exclusive::new, subsequent
-            // accesses will also fail.
-            let x = Exclusive::new(1);
-            let x2 = x.clone();
-            let _ = task::try(proc() {
-                x2.with(|one| assert_eq!(*one, 2))
-            });
-            x.with(|one| assert_eq!(*one, 1));
-        }
-    }
-}