about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/Cargo.toml4
-rw-r--r--src/libstd/build.rs40
-rw-r--r--src/libstd/collections/hash/bench.rs1
-rw-r--r--src/libstd/collections/hash/map.rs350
-rw-r--r--src/libstd/collections/hash/table.rs345
-rw-r--r--src/libstd/collections/mod.rs6
-rw-r--r--src/libstd/env.rs67
-rw-r--r--src/libstd/error.rs84
-rw-r--r--src/libstd/ffi/c_str.rs85
-rw-r--r--src/libstd/ffi/mod.rs2
-rw-r--r--src/libstd/fs.rs181
-rw-r--r--src/libstd/io/buffered.rs2
-rw-r--r--src/libstd/io/cursor.rs2
-rw-r--r--src/libstd/io/error.rs25
-rw-r--r--src/libstd/io/lazy.rs21
-rw-r--r--src/libstd/io/mod.rs38
-rw-r--r--src/libstd/io/util.rs29
-rw-r--r--src/libstd/lib.rs9
-rw-r--r--src/libstd/macros.rs16
-rw-r--r--src/libstd/memchr.rs2
-rw-r--r--src/libstd/net/addr.rs10
-rw-r--r--src/libstd/net/ip.rs182
-rw-r--r--src/libstd/net/mod.rs9
-rw-r--r--src/libstd/num/f32.rs81
-rw-r--r--src/libstd/num/f64.rs75
-rw-r--r--src/libstd/num/mod.rs9
-rw-r--r--src/libstd/os/android/raw.rs3
-rw-r--r--src/libstd/os/bitrig/raw.rs3
-rw-r--r--src/libstd/os/dragonfly/raw.rs3
-rw-r--r--src/libstd/os/emscripten/raw.rs3
-rw-r--r--src/libstd/os/freebsd/raw.rs3
-rw-r--r--src/libstd/os/ios/raw.rs3
-rw-r--r--src/libstd/os/linux/raw.rs3
-rw-r--r--src/libstd/os/macos/raw.rs3
-rw-r--r--src/libstd/os/nacl/raw.rs3
-rw-r--r--src/libstd/os/netbsd/raw.rs3
-rw-r--r--src/libstd/os/openbsd/raw.rs3
-rw-r--r--src/libstd/os/solaris/raw.rs3
-rw-r--r--src/libstd/panic.rs188
-rw-r--r--src/libstd/panicking.rs241
-rw-r--r--src/libstd/path.rs62
-rw-r--r--src/libstd/primitive_docs.rs38
-rw-r--r--src/libstd/process.rs288
-rw-r--r--src/libstd/rt.rs9
-rw-r--r--src/libstd/sync/barrier.rs2
-rw-r--r--src/libstd/sync/condvar.rs344
-rw-r--r--src/libstd/sync/mod.rs12
-rw-r--r--src/libstd/sync/mpsc/blocking.rs14
-rw-r--r--src/libstd/sync/mpsc/mod.rs369
-rw-r--r--src/libstd/sync/mpsc/oneshot.rs15
-rw-r--r--src/libstd/sync/mpsc/shared.rs17
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs13
-rw-r--r--src/libstd/sync/mpsc/stream.rs15
-rw-r--r--src/libstd/sync/mpsc/sync.rs77
-rw-r--r--src/libstd/sync/mutex.rs197
-rw-r--r--src/libstd/sync/once.rs10
-rw-r--r--src/libstd/sync/rwlock.rs329
-rw-r--r--src/libstd/sys/common/args.rs16
-rw-r--r--src/libstd/sys/common/backtrace.rs4
-rw-r--r--src/libstd/sys/common/dwarf/eh.rs159
-rw-r--r--src/libstd/sys/common/dwarf/mod.rs107
-rw-r--r--src/libstd/sys/common/gnu/libbacktrace.rs49
-rw-r--r--src/libstd/sys/common/libunwind.rs158
-rw-r--r--src/libstd/sys/common/mod.rs3
-rw-r--r--src/libstd/sys/common/mutex.rs6
-rw-r--r--src/libstd/sys/common/net.rs67
-rw-r--r--src/libstd/sys/common/poison.rs24
-rw-r--r--src/libstd/sys/common/unwind/gcc.rs280
-rw-r--r--src/libstd/sys/common/unwind/mod.rs241
-rw-r--r--src/libstd/sys/common/unwind/seh.rs153
-rw-r--r--src/libstd/sys/common/unwind/seh64_gnu.rs145
-rw-r--r--src/libstd/sys/common/util.rs34
-rw-r--r--src/libstd/sys/common/wtf8.rs6
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs28
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/gcc_s.rs164
-rw-r--r--src/libstd/sys/unix/ext/fs.rs30
-rw-r--r--src/libstd/sys/unix/ext/net.rs72
-rw-r--r--src/libstd/sys/unix/ext/process.rs29
-rw-r--r--src/libstd/sys/unix/ext/raw.rs2
-rw-r--r--src/libstd/sys/unix/fd.rs31
-rw-r--r--src/libstd/sys/unix/fs.rs47
-rw-r--r--src/libstd/sys/unix/mod.rs25
-rw-r--r--src/libstd/sys/unix/mutex.rs33
-rw-r--r--src/libstd/sys/unix/net.rs8
-rw-r--r--src/libstd/sys/unix/os.rs103
-rw-r--r--src/libstd/sys/unix/pipe.rs24
-rw-r--r--src/libstd/sys/unix/process.rs29
-rw-r--r--src/libstd/sys/unix/rand.rs17
-rw-r--r--src/libstd/sys/unix/rwlock.rs76
-rw-r--r--src/libstd/sys/unix/thread.rs22
-rw-r--r--src/libstd/sys/unix/time.rs320
-rw-r--r--src/libstd/sys/windows/backtrace.rs92
-rw-r--r--src/libstd/sys/windows/c.rs54
-rw-r--r--src/libstd/sys/windows/ext/fs.rs19
-rw-r--r--src/libstd/sys/windows/ext/process.rs15
-rw-r--r--src/libstd/sys/windows/fs.rs7
-rw-r--r--src/libstd/sys/windows/handle.rs4
-rw-r--r--src/libstd/sys/windows/mod.rs20
-rw-r--r--src/libstd/sys/windows/mutex.rs2
-rw-r--r--src/libstd/sys/windows/net.rs24
-rw-r--r--src/libstd/sys/windows/os.rs27
-rw-r--r--src/libstd/sys/windows/pipe.rs5
-rw-r--r--src/libstd/sys/windows/process.rs33
-rw-r--r--src/libstd/thread/local.rs42
-rw-r--r--src/libstd/thread/mod.rs192
-rw-r--r--src/libstd/thread/scoped_tls.rs298
-rw-r--r--src/libstd/time/duration.rs8
-rw-r--r--src/libstd/time/mod.rs17
108 files changed, 3571 insertions, 3751 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 29bd28b6160..eded6e24f3e 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -8,17 +8,19 @@ build = "build.rs"
 name = "std"
 path = "lib.rs"
 crate-type = ["dylib", "rlib"]
-test = false
 
 [dependencies]
 alloc = { path = "../liballoc" }
 alloc_jemalloc = { path = "../liballoc_jemalloc", optional = true }
 alloc_system = { path = "../liballoc_system" }
+panic_unwind = { path = "../libpanic_unwind" }
+panic_abort = { path = "../libpanic_abort" }
 collections = { path = "../libcollections" }
 core = { path = "../libcore" }
 libc = { path = "../rustc/libc_shim" }
 rand = { path = "../librand" }
 rustc_unicode = { path = "../librustc_unicode" }
+unwind = { path = "../libunwind" }
 
 [build-dependencies]
 build_helper = { path = "../build_helper" }
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index c32bca82bd5..9c408366f8b 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -8,11 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![deny(warnings)]
+
 extern crate gcc;
 extern crate build_helper;
 
 use std::env;
-use std::fs;
 use std::path::PathBuf;
 use std::process::Command;
 
@@ -20,6 +21,7 @@ use build_helper::run;
 
 fn main() {
     println!("cargo:rustc-cfg=cargobuild");
+    println!("cargo:rerun-if-changed=build.rs");
 
     let target = env::var("TARGET").unwrap();
     let host = env::var("HOST").unwrap();
@@ -28,9 +30,7 @@ fn main() {
     }
 
     if target.contains("linux") {
-        if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
-            println!("cargo:rustc-link-lib=static=unwind");
-        } else if target.contains("android") {
+        if target.contains("android") {
             println!("cargo:rustc-link-lib=dl");
             println!("cargo:rustc-link-lib=log");
             println!("cargo:rustc-link-lib=gcc");
@@ -38,27 +38,13 @@ fn main() {
             println!("cargo:rustc-link-lib=dl");
             println!("cargo:rustc-link-lib=rt");
             println!("cargo:rustc-link-lib=pthread");
-            println!("cargo:rustc-link-lib=gcc_s");
         }
     } else if target.contains("freebsd") {
         println!("cargo:rustc-link-lib=execinfo");
         println!("cargo:rustc-link-lib=pthread");
-        println!("cargo:rustc-link-lib=gcc_s");
     } else if target.contains("dragonfly") || target.contains("bitrig") ||
               target.contains("netbsd") || target.contains("openbsd") {
         println!("cargo:rustc-link-lib=pthread");
-
-        if target.contains("rumprun") {
-            println!("cargo:rustc-link-lib=unwind");
-        } else if target.contains("netbsd") {
-            println!("cargo:rustc-link-lib=gcc_s");
-        } else if target.contains("openbsd") {
-            println!("cargo:rustc-link-lib=gcc");
-        } else if target.contains("bitrig") {
-            println!("cargo:rustc-link-lib=c++abi");
-        } else if target.contains("dragonfly") {
-            println!("cargo:rustc-link-lib=gcc_pic");
-        }
     } else if target.contains("apple-darwin") {
         println!("cargo:rustc-link-lib=System");
     } else if target.contains("apple-ios") {
@@ -67,9 +53,6 @@ fn main() {
         println!("cargo:rustc-link-lib=framework=Security");
         println!("cargo:rustc-link-lib=framework=Foundation");
     } else if target.contains("windows") {
-        if target.contains("windows-gnu") {
-            println!("cargo:rustc-link-lib=gcc_eh");
-        }
         println!("cargo:rustc-link-lib=advapi32");
         println!("cargo:rustc-link-lib=ws2_32");
         println!("cargo:rustc-link-lib=userenv");
@@ -84,12 +67,21 @@ fn build_libbacktrace(host: &str, target: &str) {
     println!("cargo:rustc-link-lib=static=backtrace");
     println!("cargo:rustc-link-search=native={}/.libs", build_dir.display());
 
-    if fs::metadata(&build_dir.join(".libs/libbacktrace.a")).is_ok() {
-        return
+    let mut stack = src_dir.read_dir().unwrap()
+                           .map(|e| e.unwrap())
+                           .collect::<Vec<_>>();
+    while let Some(entry) = stack.pop() {
+        let path = entry.path();
+        if entry.file_type().unwrap().is_dir() {
+            stack.extend(path.read_dir().unwrap().map(|e| e.unwrap()));
+        } else {
+            println!("cargo:rerun-if-changed={}", path.display());
+        }
     }
 
     let compiler = gcc::Config::new().get_compiler();
-    let ar = build_helper::cc2ar(compiler.path(), target);
+    // only msvc returns None for ar so unwrap is okay
+    let ar = build_helper::cc2ar(compiler.path(), target).unwrap();
     let cflags = compiler.args().iter().map(|s| s.to_str().unwrap())
                          .collect::<Vec<_>>().join(" ");
     run(Command::new("sh")
diff --git a/src/libstd/collections/hash/bench.rs b/src/libstd/collections/hash/bench.rs
index 9fae9af2d54..a1275d23d57 100644
--- a/src/libstd/collections/hash/bench.rs
+++ b/src/libstd/collections/hash/bench.rs
@@ -11,7 +11,6 @@
 #![cfg(test)]
 
 extern crate test;
-use prelude::v1::*;
 
 use self::test::Bencher;
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index abb33b33f3f..fd7b0a2e6bb 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -14,7 +14,7 @@ use self::VacantEntryState::*;
 use borrow::Borrow;
 use cmp::max;
 use fmt::{self, Debug};
-use hash::{Hash, SipHasher, BuildHasher};
+use hash::{Hash, Hasher, BuildHasher, SipHasher13};
 use iter::FromIterator;
 use mem::{self, replace};
 use ops::{Deref, Index};
@@ -202,8 +202,10 @@ fn test_resize_policy() {
 /// The hashes are all keyed by the thread-local random number generator
 /// on creation by default. This means that the ordering of the keys is
 /// randomized, but makes the tables more resistant to
-/// denial-of-service attacks (Hash DoS). This behavior can be
-/// overridden with one of the constructors.
+/// denial-of-service attacks (Hash DoS). No guarantees are made to the
+/// quality of the random data. The implementation uses the best available
+/// random data from your platform at the time of creation. This behavior
+/// can be overridden with one of the constructors.
 ///
 /// It is required that the keys implement the `Eq` and `Hash` traits, although
 /// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.
@@ -862,7 +864,6 @@ impl<K, V, S> HashMap<K, V, S>
     /// # Examples
     ///
     /// ```
-    /// # #![feature(map_values_mut)]
     /// use std::collections::HashMap;
     ///
     /// let mut map = HashMap::new();
@@ -876,11 +877,11 @@ impl<K, V, S> HashMap<K, V, S>
     /// }
     ///
     /// for val in map.values() {
-    ///     print!("{}", val);
+    ///     println!("{}", val);
     /// }
     /// ```
-    #[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
-    pub fn values_mut<'a>(&'a mut self) -> ValuesMut<K, V> {
+    #[stable(feature = "map_values_mut", since = "1.10.0")]
+    pub fn values_mut(&mut self) -> ValuesMut<K, V> {
         ValuesMut { inner: self.iter_mut() }
     }
 
@@ -1286,7 +1287,7 @@ pub struct Drain<'a, K: 'a, V: 'a> {
 }
 
 /// Mutable HashMap values iterator.
-#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
+#[stable(feature = "map_values_mut", since = "1.10.0")]
 pub struct ValuesMut<'a, K: 'a, V: 'a> {
     inner: IterMut<'a, K, V>
 }
@@ -1335,6 +1336,10 @@ impl<'a, K, V> InternalEntry<K, V, &'a mut RawTable<K, V>> {
 }
 
 /// A view into a single location in a map, which may be vacant or occupied.
+/// This enum is constructed from the [`entry`] method on [`HashMap`].
+///
+/// [`HashMap`]: struct.HashMap.html
+/// [`entry`]: struct.HashMap.html#method.entry
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Entry<'a, K: 'a, V: 'a> {
     /// An occupied Entry.
@@ -1350,14 +1355,44 @@ pub enum Entry<'a, K: 'a, V: 'a> {
     ),
 }
 
+#[stable(feature= "debug_hash_map", since = "1.12.0")]
+impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Entry<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Vacant(ref v) => f.debug_tuple("Entry")
+                              .field(v)
+                              .finish(),
+            Occupied(ref o) => f.debug_tuple("Entry")
+                                .field(o)
+                                .finish(),
+        }
+    }
+}
+
 /// A view into a single occupied location in a HashMap.
+/// It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
     key: Option<K>,
     elem: FullBucket<K, V, &'a mut RawTable<K, V>>,
 }
 
+#[stable(feature= "debug_hash_map", since = "1.12.0")]
+impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("OccupiedEntry")
+         .field("key", self.key())
+         .field("value", self.get())
+         .finish()
+    }
+}
+
 /// A view into a single empty location in a HashMap.
+/// It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct VacantEntry<'a, K: 'a, V: 'a> {
     hash: SafeHash,
@@ -1365,6 +1400,15 @@ pub struct VacantEntry<'a, K: 'a, V: 'a> {
     elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
 }
 
+#[stable(feature= "debug_hash_map", since = "1.12.0")]
+impl<'a, K: 'a + Debug, V: 'a> Debug for VacantEntry<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("VacantEntry")
+         .field(self.key())
+         .finish()
+    }
+}
+
 /// Possible states of a VacantEntry.
 enum VacantEntryState<K, V, M> {
     /// The index is occupied, but the key to insert has precedence,
@@ -1489,14 +1533,14 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
 
-#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
+#[stable(feature = "map_values_mut", since = "1.10.0")]
 impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
     type Item = &'a mut V;
 
     #[inline] fn next(&mut self) -> Option<(&'a mut V)> { self.inner.next().map(|(_, v)| v) }
     #[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
 }
-#[unstable(feature = "map_values_mut", reason = "recently added", issue = "32551")]
+#[stable(feature = "map_values_mut", since = "1.10.0")]
 impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
     #[inline] fn len(&self) -> usize { self.inner.len() }
 }
@@ -1517,6 +1561,20 @@ impl<'a, K, V> Entry<'a, K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Ensures a value is in the entry by inserting the default if empty, and returns
     /// a mutable reference to the value in the entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// assert_eq!(map["poneyland"], 12);
+    ///
+    /// *map.entry("poneyland").or_insert(12) += 10;
+    /// assert_eq!(map["poneyland"], 22);
+    /// ```
     pub fn or_insert(self, default: V) -> &'a mut V {
         match self {
             Occupied(entry) => entry.into_mut(),
@@ -1527,6 +1585,19 @@ impl<'a, K, V> Entry<'a, K, V> {
     #[stable(feature = "rust1", since = "1.0.0")]
     /// Ensures a value is in the entry by inserting the result of the default function if empty,
     /// and returns a mutable reference to the value in the entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<&str, String> = HashMap::new();
+    /// let s = "hoho".to_owned();
+    ///
+    /// map.entry("poneyland").or_insert_with(|| s);
+    ///
+    /// assert_eq!(map["poneyland"], "hoho".to_owned());
+    /// ```
     pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
         match self {
             Occupied(entry) => entry.into_mut(),
@@ -1535,7 +1606,16 @@ impl<'a, K, V> Entry<'a, K, V> {
     }
 
     /// Returns a reference to this entry's key.
-    #[unstable(feature = "map_entry_keys", issue = "32281")]
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
+    /// ```
+    #[stable(feature = "map_entry_keys", since = "1.10.0")]
     pub fn key(&self) -> &K {
         match *self {
             Occupied(ref entry) => entry.key(),
@@ -1546,31 +1626,130 @@ impl<'a, K, V> Entry<'a, K, V> {
 
 impl<'a, K, V> OccupiedEntry<'a, K, V> {
     /// Gets a reference to the key in the entry.
-    #[unstable(feature = "map_entry_keys", issue = "32281")]
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
+    /// ```
+    #[stable(feature = "map_entry_keys", since = "1.10.0")]
     pub fn key(&self) -> &K {
         self.elem.read().0
     }
 
+    /// Take the ownership of the key and value from the map.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(map_entry_recover_keys)]
+    ///
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// if let Entry::Occupied(o) = map.entry("poneyland") {
+    ///     // We delete the entry from the map.
+    ///     o.remove_pair();
+    /// }
+    ///
+    /// assert_eq!(map.contains_key("poneyland"), false);
+    /// ```
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    pub fn remove_pair(self) -> (K, V) {
+        pop_internal(self.elem)
+    }
+
     /// Gets a reference to the value in the entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// if let Entry::Occupied(o) = map.entry("poneyland") {
+    ///     assert_eq!(o.get(), &12);
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get(&self) -> &V {
         self.elem.read().1
     }
 
     /// Gets a mutable reference to the value in the entry.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// assert_eq!(map["poneyland"], 12);
+    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
+    ///      *o.get_mut() += 10;
+    /// }
+    ///
+    /// assert_eq!(map["poneyland"], 22);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut(&mut self) -> &mut V {
         self.elem.read_mut().1
     }
 
     /// Converts the OccupiedEntry into a mutable reference to the value in the entry
-    /// with a lifetime bound to the map itself
+    /// with a lifetime bound to the map itself.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// assert_eq!(map["poneyland"], 12);
+    /// if let Entry::Occupied(o) = map.entry("poneyland") {
+    ///     *o.into_mut() += 10;
+    /// }
+    ///
+    /// assert_eq!(map["poneyland"], 22);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn into_mut(self) -> &'a mut V {
         self.elem.into_mut_refs().1
     }
 
-    /// Sets the value of the entry, and returns the entry's old value
+    /// Sets the value of the entry, and returns the entry's old value.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
+    ///     assert_eq!(o.insert(15), 12);
+    /// }
+    ///
+    /// assert_eq!(map["poneyland"], 15);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(&mut self, mut value: V) -> V {
         let old_value = self.get_mut();
@@ -1578,11 +1757,28 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
         value
     }
 
-    /// Takes the value out of the entry, and returns it
+    /// Takes the value out of the entry, and returns it.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// map.entry("poneyland").or_insert(12);
+    ///
+    /// if let Entry::Occupied(o) = map.entry("poneyland") {
+    ///     assert_eq!(o.remove(), 12);
+    /// }
+    ///
+    /// assert_eq!(map.contains_key("poneyland"), false);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove(self) -> V {
         pop_internal(self.elem).1
     }
+
     /// Returns a key that was used for search.
     ///
     /// The key was retained for further use.
@@ -1593,14 +1789,58 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
 
 impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     /// Gets a reference to the key that would be used when inserting a value
-    /// through the VacantEntry.
-    #[unstable(feature = "map_entry_keys", issue = "32281")]
+    /// through the `VacantEntry`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
+    /// ```
+    #[stable(feature = "map_entry_keys", since = "1.10.0")]
     pub fn key(&self) -> &K {
         &self.key
     }
 
+    /// Take ownership of the key.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(map_entry_recover_keys)]
+    ///
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    ///
+    /// if let Entry::Vacant(v) = map.entry("poneyland") {
+    ///     v.into_key();
+    /// }
+    /// ```
+    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
+    pub fn into_key(self) -> K {
+        self.key
+    }
+
     /// Sets the value of the entry with the VacantEntry's key,
-    /// and returns a mutable reference to it
+    /// and returns a mutable reference to it.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    /// use std::collections::hash_map::Entry;
+    ///
+    /// let mut map: HashMap<&str, u32> = HashMap::new();
+    ///
+    /// if let Entry::Vacant(o) = map.entry("poneyland") {
+    ///     o.insert(37);
+    /// }
+    /// assert_eq!(map["poneyland"], 37);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(self, value: V) -> &'a mut V {
         match self.elem {
@@ -1652,6 +1892,17 @@ impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap<K, V, S>
 /// A particular instance `RandomState` will create the same instances of
 /// `Hasher`, but the hashers created by two different `RandomState`
 /// instances are unlikely to produce the same result for the same values.
+///
+/// # Examples
+///
+/// ```
+/// use std::collections::HashMap;
+/// use std::collections::hash_map::RandomState;
+///
+/// let s = RandomState::new();
+/// let mut map = HashMap::with_hasher(s);
+/// map.insert(1, 2);
+/// ```
 #[derive(Clone)]
 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
 pub struct RandomState {
@@ -1661,21 +1912,74 @@ pub struct RandomState {
 
 impl RandomState {
     /// Constructs a new `RandomState` that is initialized with random keys.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// ```
     #[inline]
     #[allow(deprecated)] // rand
     #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
     pub fn new() -> RandomState {
-        let mut r = rand::thread_rng();
-        RandomState { k0: r.gen(), k1: r.gen() }
+        // Historically this function did not cache keys from the OS and instead
+        // simply always called `rand::thread_rng().gen()` twice. In #31356 it
+        // was discovered, however, that because we re-seed the thread-local RNG
+        // from the OS periodically that this can cause excessive slowdown when
+        // many hash maps are created on a thread. To solve this performance
+        // trap we cache the first set of randomly generated keys per-thread.
+        //
+        // In doing this, however, we lose the property that all hash maps have
+        // nondeterministic iteration order as all of those created on the same
+        // thread would have the same hash keys. This property has been nice in
+        // the past as it allows for maximal flexibility in the implementation
+        // of `HashMap` itself.
+        //
+        // The constraint here (if there even is one) is just that maps created
+        // on the same thread have the same iteration order, and that *may* be
+        // relied upon even though it is not a documented guarantee at all of
+        // the `HashMap` type. In any case we've decided that this is reasonable
+        // for now, so caching keys thread-locally seems fine.
+        thread_local!(static KEYS: (u64, u64) = {
+            let r = rand::OsRng::new();
+            let mut r = r.expect("failed to create an OS RNG");
+            (r.gen(), r.gen())
+        });
+
+        KEYS.with(|&(k0, k1)| {
+            RandomState { k0: k0, k1: k1 }
+        })
     }
 }
 
 #[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
 impl BuildHasher for RandomState {
-    type Hasher = SipHasher;
+    type Hasher = DefaultHasher;
+    #[inline]
+    fn build_hasher(&self) -> DefaultHasher {
+        DefaultHasher(SipHasher13::new_with_keys(self.k0, self.k1))
+    }
+}
+
+/// The default `Hasher` used by `RandomState`.
+///
+/// The internal algorithm is not specified, and so it and its hashes should
+/// not be relied upon over releases.
+#[unstable(feature = "hashmap_default_hasher", issue = "0")]
+pub struct DefaultHasher(SipHasher13);
+
+#[unstable(feature = "hashmap_default_hasher", issue = "0")]
+impl Hasher for DefaultHasher {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        self.0.write(msg)
+    }
+
     #[inline]
-    fn build_hasher(&self) -> SipHasher {
-        SipHasher::new_with_keys(self.k0, self.k1)
+    fn finish(&self) -> u64 {
+        self.0.finish()
     }
 }
 
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index cf64e5d3336..c4c4cb45313 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use alloc::heap::{allocate, deallocate, EMPTY};
+use alloc::heap::{EMPTY, allocate, deallocate};
 
 use cmp;
-use hash::{Hash, Hasher, BuildHasher};
+use hash::{BuildHasher, Hash, Hasher};
 use intrinsics::needs_drop;
 use marker;
 use mem::{align_of, size_of};
@@ -62,12 +62,12 @@ const EMPTY_BUCKET: u64 = 0;
 #[unsafe_no_drop_flag]
 pub struct RawTable<K, V> {
     capacity: usize,
-    size:     usize,
-    hashes:   Unique<u64>,
+    size: usize,
+    hashes: Unique<u64>,
 
     // Because K/V do not appear directly in any of the types in the struct,
     // inform rustc that in fact instances of K and V are reachable from here.
-    marker:   marker::PhantomData<(K,V)>,
+    marker: marker::PhantomData<(K, V)>,
 }
 
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
@@ -77,44 +77,48 @@ struct RawBucket<K, V> {
     hash: *mut u64,
 
     // We use *const to ensure covariance with respect to K and V
-    key:  *const K,
-    val:  *const V,
-    _marker: marker::PhantomData<(K,V)>,
+    key: *const K,
+    val: *const V,
+    _marker: marker::PhantomData<(K, V)>,
 }
 
-impl<K,V> Copy for RawBucket<K,V> {}
-impl<K,V> Clone for RawBucket<K,V> {
-    fn clone(&self) -> RawBucket<K, V> { *self }
+impl<K, V> Copy for RawBucket<K, V> {}
+impl<K, V> Clone for RawBucket<K, V> {
+    fn clone(&self) -> RawBucket<K, V> {
+        *self
+    }
 }
 
 pub struct Bucket<K, V, M> {
-    raw:   RawBucket<K, V>,
-    idx:   usize,
-    table: M
+    raw: RawBucket<K, V>,
+    idx: usize,
+    table: M,
 }
 
-impl<K,V,M:Copy> Copy for Bucket<K,V,M> {}
-impl<K,V,M:Copy> Clone for Bucket<K,V,M> {
-    fn clone(&self) -> Bucket<K,V,M> { *self }
+impl<K, V, M: Copy> Copy for Bucket<K, V, M> {}
+impl<K, V, M: Copy> Clone for Bucket<K, V, M> {
+    fn clone(&self) -> Bucket<K, V, M> {
+        *self
+    }
 }
 
 pub struct EmptyBucket<K, V, M> {
-    raw:   RawBucket<K, V>,
-    idx:   usize,
-    table: M
+    raw: RawBucket<K, V>,
+    idx: usize,
+    table: M,
 }
 
 pub struct FullBucket<K, V, M> {
-    raw:   RawBucket<K, V>,
-    idx:   usize,
-    table: M
+    raw: RawBucket<K, V>,
+    idx: usize,
+    table: M,
 }
 
 pub type EmptyBucketImm<'table, K, V> = EmptyBucket<K, V, &'table RawTable<K, V>>;
-pub type  FullBucketImm<'table, K, V> =  FullBucket<K, V, &'table RawTable<K, V>>;
+pub type FullBucketImm<'table, K, V> = FullBucket<K, V, &'table RawTable<K, V>>;
 
 pub type EmptyBucketMut<'table, K, V> = EmptyBucket<K, V, &'table mut RawTable<K, V>>;
-pub type  FullBucketMut<'table, K, V> =  FullBucket<K, V, &'table mut RawTable<K, V>>;
+pub type FullBucketMut<'table, K, V> = FullBucket<K, V, &'table mut RawTable<K, V>>;
 
 pub enum BucketState<K, V, M> {
     Empty(EmptyBucket<K, V, M>),
@@ -139,14 +143,17 @@ pub struct SafeHash {
 impl SafeHash {
     /// Peek at the hash value, which is guaranteed to be non-zero.
     #[inline(always)]
-    pub fn inspect(&self) -> u64 { self.hash }
+    pub fn inspect(&self) -> u64 {
+        self.hash
+    }
 }
 
 /// We need to remove hashes of 0. That's reserved for empty buckets.
 /// This function wraps up `hash_keyed` to be the only way outside this
 /// module to generate a SafeHash.
 pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash
-    where T: Hash, S: BuildHasher
+    where T: Hash,
+          S: BuildHasher
 {
     let mut state = hash_state.build_hasher();
     t.hash(&mut state);
@@ -175,8 +182,8 @@ impl<K, V> RawBucket<K, V> {
     unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
         RawBucket {
             hash: self.hash.offset(count),
-            key:  self.key.offset(count),
-            val:  self.val.offset(count),
+            key: self.key.offset(count),
+            val: self.val.offset(count),
             _marker: marker::PhantomData,
         }
     }
@@ -212,7 +219,9 @@ impl<K, V, M> Bucket<K, V, M> {
     }
 }
 
-impl<K, V, M> Deref for FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> {
+impl<K, V, M> Deref for FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>>
+{
     type Target = RawTable<K, V>;
     fn deref(&self) -> &RawTable<K, V> {
         &self.table
@@ -232,19 +241,23 @@ impl<'t, K, V> Put<K, V> for &'t mut RawTable<K, V> {
     }
 }
 
-impl<K, V, M> Put<K, V> for Bucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> Put<K, V> for Bucket<K, V, M>
+    where M: Put<K, V>
+{
     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
         self.table.borrow_table_mut()
     }
 }
 
-impl<K, V, M> Put<K, V> for FullBucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> Put<K, V> for FullBucket<K, V, M>
+    where M: Put<K, V>
+{
     unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> {
         self.table.borrow_table_mut()
     }
 }
 
-impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
+impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
     pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as usize)
     }
@@ -252,14 +265,13 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
     pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
         // if capacity is 0, then the RawBucket will be populated with bogus pointers.
         // This is an uncommon case though, so avoid it in release builds.
-        debug_assert!(table.capacity() > 0, "Table should have capacity at this point");
+        debug_assert!(table.capacity() > 0,
+                      "Table should have capacity at this point");
         let ib_index = ib_index & (table.capacity() - 1);
         Bucket {
-            raw: unsafe {
-               table.first_bucket_raw().offset(ib_index as isize)
-            },
+            raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
             idx: ib_index,
-            table: table
+            table: table,
         }
     }
 
@@ -267,7 +279,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
         Bucket {
             raw: table.first_bucket_raw(),
             idx: 0,
-            table: table
+            table: table,
         }
     }
 
@@ -277,18 +289,20 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
     /// this module.
     pub fn peek(self) -> BucketState<K, V, M> {
         match unsafe { *self.raw.hash } {
-            EMPTY_BUCKET =>
+            EMPTY_BUCKET => {
                 Empty(EmptyBucket {
                     raw: self.raw,
                     idx: self.idx,
-                    table: self.table
-                }),
-            _ =>
+                    table: self.table,
+                })
+            }
+            _ => {
                 Full(FullBucket {
                     raw: self.raw,
                     idx: self.idx,
-                    table: self.table
+                    table: self.table,
                 })
+            }
         }
     }
 
@@ -308,7 +322,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> Bucket<K, V, M> {
     }
 }
 
-impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
+impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
     #[inline]
     pub fn next(self) -> Bucket<K, V, M> {
         let mut bucket = self.into_bucket();
@@ -321,7 +335,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
         Bucket {
             raw: self.raw,
             idx: self.idx,
-            table: self.table
+            table: self.table,
         }
     }
 
@@ -329,22 +343,24 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> EmptyBucket<K, V, M> {
         let gap = EmptyBucket {
             raw: self.raw,
             idx: self.idx,
-            table: ()
+            table: (),
         };
 
         match self.next().peek() {
             Full(bucket) => {
                 Some(GapThenFull {
                     gap: gap,
-                    full: bucket
+                    full: bucket,
                 })
             }
-            Empty(..) => None
+            Empty(..) => None,
         }
     }
 }
 
-impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> EmptyBucket<K, V, M>
+    where M: Put<K, V>
+{
     /// Puts given key and value pair, along with the key's hash,
     /// into this bucket in the hashtable. Note how `self` is 'moved' into
     /// this function, because this slot will no longer be empty when
@@ -352,8 +368,7 @@ impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
     /// the newly-filled slot in the hashtable.
     ///
     /// Use `make_hash` to construct a `SafeHash` to pass to this function.
-    pub fn put(mut self, hash: SafeHash, key: K, value: V)
-               -> FullBucket<K, V, M> {
+    pub fn put(mut self, hash: SafeHash, key: K, value: V) -> FullBucket<K, V, M> {
         unsafe {
             *self.raw.hash = hash.inspect();
             ptr::write(self.raw.key as *mut K, key);
@@ -362,11 +377,15 @@ impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
             self.table.borrow_table_mut().size += 1;
         }
 
-        FullBucket { raw: self.raw, idx: self.idx, table: self.table }
+        FullBucket {
+            raw: self.raw,
+            idx: self.idx,
+            table: self.table,
+        }
     }
 }
 
-impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
+impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
     #[inline]
     pub fn next(self) -> Bucket<K, V, M> {
         let mut bucket = self.into_bucket();
@@ -379,7 +398,7 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
         Bucket {
             raw: self.raw,
             idx: self.idx,
-            table: self.table
+            table: self.table,
         }
     }
 
@@ -407,19 +426,12 @@ impl<K, V, M: Deref<Target=RawTable<K, V>>> FullBucket<K, V, M> {
 
     #[inline]
     pub fn hash(&self) -> SafeHash {
-        unsafe {
-            SafeHash {
-                hash: *self.raw.hash
-            }
-        }
+        unsafe { SafeHash { hash: *self.raw.hash } }
     }
 
     /// Gets references to the key and value at a given index.
     pub fn read(&self) -> (&K, &V) {
-        unsafe {
-            (&*self.raw.key,
-             &*self.raw.val)
-        }
+        unsafe { (&*self.raw.key, &*self.raw.val) }
     }
 }
 
@@ -436,69 +448,68 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
 
         unsafe {
             *self.raw.hash = EMPTY_BUCKET;
-            (
-                EmptyBucket {
-                    raw: self.raw,
-                    idx: self.idx,
-                    table: self.table
-                },
-                ptr::read(self.raw.key),
-                ptr::read(self.raw.val)
-            )
+            (EmptyBucket {
+                raw: self.raw,
+                idx: self.idx,
+                table: self.table,
+            },
+             ptr::read(self.raw.key),
+             ptr::read(self.raw.val))
         }
     }
 }
 
 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
 // where `M` is a full bucket or table reference type with mutable access to the table.
-impl<K, V, M> FullBucket<K, V, M> where M: Put<K, V> {
+impl<K, V, M> FullBucket<K, V, M>
+    where M: Put<K, V>
+{
     pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
         unsafe {
             let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
-            let old_key  = ptr::replace(self.raw.key as *mut K,  k);
-            let old_val  = ptr::replace(self.raw.val as *mut V,  v);
+            let old_key = ptr::replace(self.raw.key as *mut K, k);
+            let old_val = ptr::replace(self.raw.val as *mut V, v);
 
             (old_hash, old_key, old_val)
         }
     }
 }
 
-impl<K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + DerefMut {
+impl<K, V, M> FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>> + DerefMut
+{
     /// Gets mutable references to the key and value at a given index.
     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
-        unsafe {
-            (&mut *(self.raw.key as *mut K),
-             &mut *(self.raw.val as *mut V))
-        }
+        unsafe { (&mut *(self.raw.key as *mut K), &mut *(self.raw.val as *mut V)) }
     }
 }
 
-impl<'t, K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + 't {
+impl<'t, K, V, M> FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>> + 't
+{
     /// Exchange a bucket state for immutable references into the table.
     /// Because the underlying reference to the table is also consumed,
     /// no further changes to the structure of the table are possible;
     /// in exchange for this, the returned references have a longer lifetime
     /// than the references returned by `read()`.
     pub fn into_refs(self) -> (&'t K, &'t V) {
-        unsafe {
-            (&*self.raw.key,
-             &*self.raw.val)
-        }
+        unsafe { (&*self.raw.key, &*self.raw.val) }
     }
 }
 
-impl<'t, K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + DerefMut + 't {
+impl<'t, K, V, M> FullBucket<K, V, M>
+    where M: Deref<Target = RawTable<K, V>> + DerefMut + 't
+{
     /// This works similarly to `into_refs`, exchanging a bucket state
     /// for mutable references into the table.
     pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
-        unsafe {
-            (&mut *(self.raw.key as *mut K),
-             &mut *(self.raw.val as *mut V))
-        }
+        unsafe { (&mut *(self.raw.key as *mut K), &mut *(self.raw.val as *mut V)) }
     }
 }
 
-impl<K, V, M> GapThenFull<K, V, M> where M: Deref<Target=RawTable<K, V>> {
+impl<K, V, M> GapThenFull<K, V, M>
+    where M: Deref<Target = RawTable<K, V>>
+{
     #[inline]
     pub fn full(&self) -> &FullBucket<K, V, M> {
         &self.full
@@ -522,7 +533,7 @@ impl<K, V, M> GapThenFull<K, V, M> where M: Deref<Target=RawTable<K, V>> {
 
                 Some(self)
             }
-            Empty(..) => None
+            Empty(..) => None,
         }
     }
 }
@@ -554,7 +565,8 @@ fn test_rounding() {
 // from the start of a mallocated array.
 #[inline]
 fn calculate_offsets(hashes_size: usize,
-                     keys_size: usize, keys_align: usize,
+                     keys_size: usize,
+                     keys_align: usize,
                      vals_align: usize)
                      -> (usize, usize, bool) {
     let keys_offset = round_up_to_next(hashes_size, keys_align);
@@ -567,14 +579,15 @@ fn calculate_offsets(hashes_size: usize,
 
 // Returns a tuple of (minimum required malloc alignment, hash_offset,
 // array_size), from the start of a mallocated array.
-fn calculate_allocation(hash_size: usize, hash_align: usize,
-                        keys_size: usize, keys_align: usize,
-                        vals_size: usize, vals_align: usize)
+fn calculate_allocation(hash_size: usize,
+                        hash_align: usize,
+                        keys_size: usize,
+                        keys_align: usize,
+                        vals_size: usize,
+                        vals_align: usize)
                         -> (usize, usize, usize, bool) {
     let hash_offset = 0;
-    let (_, vals_offset, oflo) = calculate_offsets(hash_size,
-                                                   keys_size, keys_align,
-                                                              vals_align);
+    let (_, vals_offset, oflo) = calculate_offsets(hash_size, keys_size, keys_align, vals_align);
     let (end_of_vals, oflo2) = vals_offset.overflowing_add(vals_size);
 
     let align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
@@ -584,12 +597,13 @@ fn calculate_allocation(hash_size: usize, hash_align: usize,
 
 #[test]
 fn test_offset_calculation() {
-    assert_eq!(calculate_allocation(128, 8, 15, 1, 4,  4), (8, 0, 148, false));
-    assert_eq!(calculate_allocation(3,   1, 2,  1, 1,  1), (1, 0, 6, false));
-    assert_eq!(calculate_allocation(6,   2, 12, 4, 24, 8), (8, 0, 48, false));
+    assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4),
+               (8, 0, 148, false));
+    assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6, false));
+    assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48, false));
     assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144, false));
-    assert_eq!(calculate_offsets(3,   2,  1, 1), (3,   5, false));
-    assert_eq!(calculate_offsets(6,   12, 4, 8), (8,   24, false));
+    assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5, false));
+    assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24, false));
 }
 
 impl<K, V> RawTable<K, V> {
@@ -608,8 +622,8 @@ impl<K, V> RawTable<K, V> {
         // No need for `checked_mul` before a more restrictive check performed
         // later in this method.
         let hashes_size = capacity * size_of::<u64>();
-        let keys_size   = capacity * size_of::< K >();
-        let vals_size   = capacity * size_of::< V >();
+        let keys_size = capacity * size_of::<K>();
+        let vals_size = capacity * size_of::<V>();
 
         // Allocating hashmaps is a little tricky. We need to allocate three
         // arrays, but since we know their sizes and alignments up front,
@@ -619,31 +633,38 @@ impl<K, V> RawTable<K, V> {
         // This is great in theory, but in practice getting the alignment
         // right is a little subtle. Therefore, calculating offsets has been
         // factored out into a different function.
-        let (malloc_alignment, hash_offset, size, oflo) =
-            calculate_allocation(
-                hashes_size, align_of::<u64>(),
-                keys_size,   align_of::< K >(),
-                vals_size,   align_of::< V >());
+        let (malloc_alignment, hash_offset, size, oflo) = calculate_allocation(hashes_size,
+                                                                               align_of::<u64>(),
+                                                                               keys_size,
+                                                                               align_of::<K>(),
+                                                                               vals_size,
+                                                                               align_of::<V>());
 
         assert!(!oflo, "capacity overflow");
 
         // One check for overflow that covers calculation and rounding of size.
-        let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
-                                             .checked_add(size_of::<V>()).unwrap();
-        assert!(size >= capacity.checked_mul(size_of_bucket)
-                                .expect("capacity overflow"),
+        let size_of_bucket = size_of::<u64>()
+                                 .checked_add(size_of::<K>())
+                                 .unwrap()
+                                 .checked_add(size_of::<V>())
+                                 .unwrap();
+        assert!(size >=
+                capacity.checked_mul(size_of_bucket)
+                        .expect("capacity overflow"),
                 "capacity overflow");
 
         let buffer = allocate(size, malloc_alignment);
-        if buffer.is_null() { ::alloc::oom() }
+        if buffer.is_null() {
+            ::alloc::oom()
+        }
 
         let hashes = buffer.offset(hash_offset as isize) as *mut u64;
 
         RawTable {
             capacity: capacity,
-            size:     0,
-            hashes:   Unique::new(hashes),
-            marker:   marker::PhantomData,
+            size: 0,
+            hashes: Unique::new(hashes),
+            marker: marker::PhantomData,
         }
     }
 
@@ -652,16 +673,16 @@ impl<K, V> RawTable<K, V> {
         let keys_size = self.capacity * size_of::<K>();
 
         let buffer = *self.hashes as *const u8;
-        let (keys_offset, vals_offset, oflo) =
-            calculate_offsets(hashes_size,
-                              keys_size, align_of::<K>(),
-                              align_of::<V>());
+        let (keys_offset, vals_offset, oflo) = calculate_offsets(hashes_size,
+                                                                 keys_size,
+                                                                 align_of::<K>(),
+                                                                 align_of::<V>());
         debug_assert!(!oflo, "capacity overflow");
         unsafe {
             RawBucket {
                 hash: *self.hashes,
-                key:  buffer.offset(keys_offset as isize) as *const K,
-                val:  buffer.offset(vals_offset as isize) as *const V,
+                key: buffer.offset(keys_offset as isize) as *const K,
+                val: buffer.offset(vals_offset as isize) as *const V,
                 _marker: marker::PhantomData,
             }
         }
@@ -691,9 +712,7 @@ impl<K, V> RawTable<K, V> {
     fn raw_buckets(&self) -> RawBuckets<K, V> {
         RawBuckets {
             raw: self.first_bucket_raw(),
-            hashes_end: unsafe {
-                self.hashes.offset(self.capacity as isize)
-            },
+            hashes_end: unsafe { self.hashes.offset(self.capacity as isize) },
             marker: marker::PhantomData,
         }
     }
@@ -747,7 +766,7 @@ impl<K, V> RawTable<K, V> {
             raw: raw_bucket.offset(self.capacity as isize),
             hashes_end: raw_bucket.hash,
             elems_left: self.size,
-            marker:     marker::PhantomData,
+            marker: marker::PhantomData,
         }
     }
 }
@@ -827,10 +846,7 @@ impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
 
                 if *self.raw.hash != EMPTY_BUCKET {
                     self.elems_left -= 1;
-                    return Some((
-                        ptr::read(self.raw.key),
-                        ptr::read(self.raw.val)
-                    ));
+                    return Some((ptr::read(self.raw.key), ptr::read(self.raw.val)));
                 }
             }
         }
@@ -851,7 +867,7 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
     fn clone(&self) -> Iter<'a, K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left
+            elems_left: self.elems_left,
         }
     }
 }
@@ -873,7 +889,7 @@ unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
 /// Iterator over the entries in a table, consuming the table.
 pub struct IntoIter<K, V> {
     table: RawTable<K, V>,
-    iter: RawBuckets<'static, K, V>
+    iter: RawBuckets<'static, K, V>,
 }
 
 unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
@@ -894,10 +910,7 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
         self.iter.next().map(|bucket| {
             self.elems_left -= 1;
-            unsafe {
-                (&*bucket.key,
-                 &*bucket.val)
-            }
+            unsafe { (&*bucket.key, &*bucket.val) }
         })
     }
 
@@ -906,7 +919,9 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     }
 }
 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
-    fn len(&self) -> usize { self.elems_left }
+    fn len(&self) -> usize {
+        self.elems_left
+    }
 }
 
 impl<'a, K, V> Iterator for IterMut<'a, K, V> {
@@ -915,10 +930,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
         self.iter.next().map(|bucket| {
             self.elems_left -= 1;
-            unsafe {
-                (&*bucket.key,
-                 &mut *(bucket.val as *mut V))
-            }
+            unsafe { (&*bucket.key, &mut *(bucket.val as *mut V)) }
         })
     }
 
@@ -927,7 +939,9 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     }
 }
 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
-    fn len(&self) -> usize { self.elems_left }
+    fn len(&self) -> usize {
+        self.elems_left
+    }
 }
 
 impl<K, V> Iterator for IntoIter<K, V> {
@@ -937,13 +951,7 @@ impl<K, V> Iterator for IntoIter<K, V> {
         self.iter.next().map(|bucket| {
             self.table.size -= 1;
             unsafe {
-                (
-                    SafeHash {
-                        hash: *bucket.hash,
-                    },
-                    ptr::read(bucket.key),
-                    ptr::read(bucket.val)
-                )
+                (SafeHash { hash: *bucket.hash }, ptr::read(bucket.key), ptr::read(bucket.val))
             }
         })
     }
@@ -954,7 +962,9 @@ impl<K, V> Iterator for IntoIter<K, V> {
     }
 }
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
-    fn len(&self) -> usize { self.table.size() }
+    fn len(&self) -> usize {
+        self.table.size()
+    }
 }
 
 impl<'a, K, V> Iterator for Drain<'a, K, V> {
@@ -965,13 +975,9 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
         self.iter.next().map(|bucket| {
             self.table.size -= 1;
             unsafe {
-                (
-                    SafeHash {
-                        hash: ptr::replace(bucket.hash, EMPTY_BUCKET),
-                    },
-                    ptr::read(bucket.key),
-                    ptr::read(bucket.val)
-                )
+                (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) },
+                 ptr::read(bucket.key),
+                 ptr::read(bucket.val))
             }
         })
     }
@@ -982,7 +988,9 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
     }
 }
 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
-    fn len(&self) -> usize { self.table.size() }
+    fn len(&self) -> usize {
+        self.table.size()
+    }
 }
 
 impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
@@ -1040,7 +1048,8 @@ impl<K, V> Drop for RawTable<K, V> {
         // dropping empty tables such as on resize.
         // Also avoid double drop of elements that have been already moved out.
         unsafe {
-            if needs_drop::<(K, V)>() { // avoid linear runtime for types that don't need drop
+            if needs_drop::<(K, V)>() {
+                // avoid linear runtime for types that don't need drop
                 for _ in self.rev_move_buckets() {}
             }
         }
@@ -1048,10 +1057,12 @@ impl<K, V> Drop for RawTable<K, V> {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
         let vals_size = self.capacity * size_of::<V>();
-        let (align, _, size, oflo) =
-            calculate_allocation(hashes_size, align_of::<u64>(),
-                                 keys_size, align_of::<K>(),
-                                 vals_size, align_of::<V>());
+        let (align, _, size, oflo) = calculate_allocation(hashes_size,
+                                                          align_of::<u64>(),
+                                                          keys_size,
+                                                          align_of::<K>(),
+                                                          vals_size,
+                                                          align_of::<V>());
 
         debug_assert!(!oflo, "should be impossible");
 
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index 44613d77671..9b13d542300 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -429,14 +429,16 @@ mod hash;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub mod hash_map {
-    //! A hashmap
+    //! A hash map implementation which uses linear probing with Robin
+    //! Hood bucket stealing.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::hash::map::*;
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub mod hash_set {
-    //! A hashset
+    //! An implementation of a hash set using the underlying representation of a
+    //! HashMap where the value is ().
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use super::hash::set::*;
 }
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index 9dc6a26cdee..d6d62ce79d4 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -452,16 +452,16 @@ pub fn home_dir() -> Option<PathBuf> {
 
 /// Returns the path of a temporary directory.
 ///
-/// On Unix, returns the value of the 'TMPDIR' environment variable if it is
-/// set, otherwise for non-Android it returns '/tmp'. If Android, since there
-/// is no global temporary folder (it is usually allocated per-app), we return
-/// '/data/local/tmp'.
+/// On Unix, returns the value of the `TMPDIR` environment variable if it is
+/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
+/// is no global temporary folder (it is usually allocated per-app), it returns
+/// `/data/local/tmp`.
 ///
-/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
-/// 'USERPROFILE' environment variable  if any are set and not the empty
-/// string. Otherwise, tmpdir returns the path of the Windows directory. This
-/// behavior is identical to that of [GetTempPath][msdn], which this function
-/// uses internally.
+/// On Windows, returns the value of, in order, the `TMP`, `TEMP`,
+/// `USERPROFILE` environment variable if any are set and not the empty
+/// string. Otherwise, `temp_dir` returns the path of the Windows directory.
+/// This behavior is identical to that of [`GetTempPath`][msdn], which this
+/// function uses internally.
 ///
 /// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx
 ///
@@ -493,6 +493,44 @@ pub fn temp_dir() -> PathBuf {
 /// that can fail for a good number of reasons. Some errors can include, but not
 /// be limited to, filesystem operations failing or general syscall failures.
 ///
+/// # Security
+///
+/// The output of this function should not be used in anything that might have
+/// security implications. For example:
+///
+/// ```
+/// fn main() {
+///     println!("{:?}", std::env::current_exe());
+/// }
+/// ```
+///
+/// On Linux systems, if this is compiled as `foo`:
+///
+/// ```bash
+/// $ rustc foo.rs
+/// $ ./foo
+/// Ok("/home/alex/foo")
+/// ```
+///
+/// And you make a symbolic link of the program:
+///
+/// ```bash
+/// $ ln foo bar
+/// ```
+///
+/// When you run it, you won't get the original executable, you'll get the
+/// symlink:
+///
+/// ```bash
+/// $ ./bar
+/// Ok("/home/alex/bar")
+/// ```
+///
+/// This sort of behavior has been known to [lead to privledge escalation] when
+/// used incorrectly, for example.
+///
+/// [lead to privledge escalation]: http://securityvulns.com/Wdocument183.html
+///
 /// # Examples
 ///
 /// ```
@@ -587,6 +625,13 @@ impl ExactSizeIterator for Args {
     fn len(&self) -> usize { self.inner.len() }
 }
 
+#[stable(feature = "env_iterators", since = "1.11.0")]
+impl DoubleEndedIterator for Args {
+    fn next_back(&mut self) -> Option<String> {
+        self.inner.next_back().map(|s| s.into_string().unwrap())
+    }
+}
+
 #[stable(feature = "env", since = "1.0.0")]
 impl Iterator for ArgsOs {
     type Item = OsString;
@@ -599,6 +644,10 @@ impl ExactSizeIterator for ArgsOs {
     fn len(&self) -> usize { self.inner.len() }
 }
 
+#[stable(feature = "env_iterators", since = "1.11.0")]
+impl DoubleEndedIterator for ArgsOs {
+    fn next_back(&mut self) -> Option<OsString> { self.inner.next_back() }
+}
 /// Constants associated with the current target
 #[stable(feature = "env", since = "1.0.0")]
 pub mod consts {
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 35cd4a5ec52..1459420cdc0 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -66,10 +66,80 @@ pub trait Error: Debug + Display + Reflect {
     /// The description should not contain newlines or sentence-ending
     /// punctuation, to facilitate embedding in larger user-facing
     /// strings.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::error::Error;
+    ///
+    /// match "xc".parse::<u32>() {
+    ///     Err(e) => {
+    ///         println!("Error: {}", e.description());
+    ///     }
+    ///     _ => println!("No error"),
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn description(&self) -> &str;
 
     /// The lower-level cause of this error, if any.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::error::Error;
+    /// use std::fmt;
+    ///
+    /// #[derive(Debug)]
+    /// struct SuperError {
+    ///     side: SuperErrorSideKick,
+    /// }
+    ///
+    /// impl fmt::Display for SuperError {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "SuperError is here!")
+    ///     }
+    /// }
+    ///
+    /// impl Error for SuperError {
+    ///     fn description(&self) -> &str {
+    ///         "I'm the superhero of errors!"
+    ///     }
+    ///
+    ///     fn cause(&self) -> Option<&Error> {
+    ///         Some(&self.side)
+    ///     }
+    /// }
+    ///
+    /// #[derive(Debug)]
+    /// struct SuperErrorSideKick;
+    ///
+    /// impl fmt::Display for SuperErrorSideKick {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "SuperErrorSideKick is here!")
+    ///     }
+    /// }
+    ///
+    /// impl Error for SuperErrorSideKick {
+    ///     fn description(&self) -> &str {
+    ///         "I'm SuperError side kick!"
+    ///     }
+    /// }
+    ///
+    /// fn get_super_error() -> Result<(), SuperError> {
+    ///     Err(SuperError { side: SuperErrorSideKick })
+    /// }
+    ///
+    /// fn main() {
+    ///     match get_super_error() {
+    ///         Err(e) => {
+    ///             println!("Error: {}", e.description());
+    ///             println!("Caused by: {}", e.cause().unwrap());
+    ///         }
+    ///         _ => println!("No error"),
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn cause(&self) -> Option<&Error> { None }
 
@@ -159,6 +229,13 @@ impl Error for num::ParseIntError {
     }
 }
 
+#[unstable(feature = "try_from", issue = "33417")]
+impl Error for num::TryFromIntError {
+    fn description(&self) -> &str {
+        self.__description()
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Error for num::ParseFloatError {
     fn description(&self) -> &str {
@@ -205,6 +282,13 @@ impl<T: Error> Error for Box<T> {
     }
 }
 
+#[stable(feature = "fmt_error", since = "1.11.0")]
+impl Error for fmt::Error {
+    fn description(&self) -> &str {
+        "an error occurred when formatting an argument"
+    }
+}
+
 // copied from any.rs
 impl Error + 'static {
     /// Returns true if the boxed type is the same as `T`
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 52d7bb128d5..0d3e18f9b96 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -159,6 +159,12 @@ pub struct CStr {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct NulError(usize, Vec<u8>);
 
+/// An error returned from `CStr::from_bytes_with_nul` to indicate that a nul
+/// byte was found too early in the slice provided or one wasn't found at all.
+#[derive(Clone, PartialEq, Debug)]
+#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
+pub struct FromBytesWithNulError { _a: () }
+
 /// An error returned from `CString::into_string` to indicate that a UTF-8 error
 /// was encountered during the conversion.
 #[derive(Clone, PartialEq, Debug)]
@@ -326,6 +332,22 @@ impl fmt::Debug for CStr {
     }
 }
 
+#[stable(feature = "cstr_default", since = "1.10.0")]
+impl<'a> Default for &'a CStr {
+    fn default() -> &'a CStr {
+        static SLICE: &'static [c_char] = &[0];
+        unsafe { CStr::from_ptr(SLICE.as_ptr()) }
+    }
+}
+
+#[stable(feature = "cstr_default", since = "1.10.0")]
+impl Default for CString {
+    fn default() -> CString {
+        let a: &CStr = Default::default();
+        a.to_owned()
+    }
+}
+
 #[stable(feature = "cstr_borrow", since = "1.3.0")]
 impl Borrow<CStr> for CString {
     fn borrow(&self) -> &CStr { self }
@@ -445,20 +467,18 @@ impl CStr {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(cstr_from_bytes)]
     /// use std::ffi::CStr;
     ///
-    /// # fn main() {
     /// let cstr = CStr::from_bytes_with_nul(b"hello\0");
-    /// assert!(cstr.is_some());
-    /// # }
+    /// assert!(cstr.is_ok());
     /// ```
-    #[unstable(feature = "cstr_from_bytes", reason = "recently added", issue = "31190")]
-    pub fn from_bytes_with_nul(bytes: &[u8]) -> Option<&CStr> {
+    #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
+    pub fn from_bytes_with_nul(bytes: &[u8])
+                               -> Result<&CStr, FromBytesWithNulError> {
         if bytes.is_empty() || memchr::memchr(0, &bytes) != Some(bytes.len() - 1) {
-            None
+            Err(FromBytesWithNulError { _a: () })
         } else {
-            Some(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
+            Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
         }
     }
 
@@ -471,18 +491,15 @@ impl CStr {
     /// # Examples
     ///
     /// ```
-    /// # #![feature(cstr_from_bytes)]
     /// use std::ffi::{CStr, CString};
     ///
-    /// # fn main() {
     /// unsafe {
     ///     let cstring = CString::new("hello").unwrap();
     ///     let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
     ///     assert_eq!(cstr, &*cstring);
     /// }
-    /// # }
     /// ```
-    #[unstable(feature = "cstr_from_bytes", reason = "recently added", issue = "31190")]
+    #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
         mem::transmute(bytes)
     }
@@ -492,6 +509,38 @@ impl CStr {
     /// The returned pointer will be valid for as long as `self` is and points
     /// to a contiguous region of memory terminated with a 0 byte to represent
     /// the end of the string.
+    ///
+    /// **WARNING**
+    ///
+    /// It is your responsibility to make sure that the underlying memory is not
+    /// freed too early. For example, the following code will cause undefined
+    /// behaviour when `ptr` is used inside the `unsafe` block:
+    ///
+    /// ```no_run
+    /// use std::ffi::{CString};
+    ///
+    /// let ptr = CString::new("Hello").unwrap().as_ptr();
+    /// unsafe {
+    ///     // `ptr` is dangling
+    ///     *ptr;
+    /// }
+    /// ```
+    ///
+    /// This happens because the pointer returned by `as_ptr` does not carry any
+    /// lifetime information and the string is deallocated immediately after
+    /// the `CString::new("Hello").unwrap().as_ptr()` expression is evaluated.
+    /// To fix the problem, bind the string to a local variable:
+    ///
+    /// ```no_run
+    /// use std::ffi::{CString};
+    ///
+    /// let hello = CString::new("Hello").unwrap();
+    /// let ptr = hello.as_ptr();
+    /// unsafe {
+    ///     // `ptr` is valid because `hello` is in scope
+    ///     *ptr;
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_ptr(&self) -> *const c_char {
         self.inner.as_ptr()
@@ -726,12 +775,14 @@ mod tests {
     fn from_bytes_with_nul() {
         let data = b"123\0";
         let cstr = CStr::from_bytes_with_nul(data);
-        assert_eq!(cstr.map(CStr::to_bytes), Some(&b"123"[..]));
-        assert_eq!(cstr.map(CStr::to_bytes_with_nul), Some(&b"123\0"[..]));
+        assert_eq!(cstr.map(CStr::to_bytes), Ok(&b"123"[..]));
+        let cstr = CStr::from_bytes_with_nul(data);
+        assert_eq!(cstr.map(CStr::to_bytes_with_nul), Ok(&b"123\0"[..]));
 
         unsafe {
+            let cstr = CStr::from_bytes_with_nul(data);
             let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
-            assert_eq!(cstr, Some(cstr_unchecked));
+            assert_eq!(cstr, Ok(cstr_unchecked));
         }
     }
 
@@ -739,13 +790,13 @@ mod tests {
     fn from_bytes_with_nul_unterminated() {
         let data = b"123";
         let cstr = CStr::from_bytes_with_nul(data);
-        assert!(cstr.is_none());
+        assert!(cstr.is_err());
     }
 
     #[test]
     fn from_bytes_with_nul_interior() {
         let data = b"1\023\0";
         let cstr = CStr::from_bytes_with_nul(data);
-        assert!(cstr.is_none());
+        assert!(cstr.is_err());
     }
 }
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
index bfd6ab52289..ca1ff18f1ca 100644
--- a/src/libstd/ffi/mod.rs
+++ b/src/libstd/ffi/mod.rs
@@ -14,6 +14,8 @@
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::c_str::{CString, CStr, NulError, IntoStringError};
+#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
+pub use self::c_str::{FromBytesWithNulError};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::os_str::{OsString, OsStr};
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 03ebaa59ca5..48753ccf1c3 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -32,6 +32,8 @@ use time::SystemTime;
 /// it was opened with. Files also implement `Seek` to alter the logical cursor
 /// that the file contains internally.
 ///
+/// Files are automatically closed when they go out of scope.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -56,28 +58,37 @@ pub struct File {
 
 /// Metadata information about a file.
 ///
-/// This structure is returned from the `metadata` function or method and
+/// This structure is returned from the [`metadata`] function or method and
 /// represents known metadata about a file such as its permissions, size,
 /// modification times, etc.
+///
+/// [`metadata`]: fn.metadata.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct Metadata(fs_imp::FileAttr);
 
 /// Iterator over the entries in a directory.
 ///
-/// This iterator is returned from the `read_dir` function of this module and
-/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
+/// This iterator is returned from the [`read_dir`] function of this module and
+/// will yield instances of `io::Result<DirEntry>`. Through a [`DirEntry`]
 /// information like the entry's path and possibly other metadata can be
 /// learned.
 ///
+/// [`read_dir`]: fn.read_dir.html
+/// [`DirEntry`]: struct.DirEntry.html
+///
 /// # Errors
 ///
-/// This `io::Result` will be an `Err` if there's some sort of intermittent
+/// This [`io::Result`] will be an `Err` if there's some sort of intermittent
 /// IO error during iteration.
+///
+/// [`io::Result`]: ../io/type.Result.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ReadDir(fs_imp::ReadDir);
 
-/// Entries returned by the `ReadDir` iterator.
+/// Entries returned by the [`ReadDir`] iterator.
+///
+/// [`ReadDir`]: struct.ReadDir.html
 ///
 /// An instance of `DirEntry` represents an entry inside of a directory on the
 /// filesystem. Each entry can be inspected via methods to learn about the full
@@ -87,17 +98,23 @@ pub struct DirEntry(fs_imp::DirEntry);
 
 /// Options and flags which can be used to configure how a file is opened.
 ///
-/// This builder exposes the ability to configure how a `File` is opened and
-/// what operations are permitted on the open file. The `File::open` and
-/// `File::create` methods are aliases for commonly used options using this
+/// This builder exposes the ability to configure how a [`File`] is opened and
+/// what operations are permitted on the open file. The [`File::open`] and
+/// [`File::create`] methods are aliases for commonly used options using this
 /// builder.
 ///
-/// Generally speaking, when using `OpenOptions`, you'll first call `new()`,
-/// then chain calls to methods to set each option, then call `open()`, passing
-/// the path of the file you're trying to open. This will give you a
+/// [`File`]: struct.File.html
+/// [`File::open`]: struct.File.html#method.open
+/// [`File::create`]: struct.File.html#method.create
+///
+/// Generally speaking, when using `OpenOptions`, you'll first call [`new()`],
+/// then chain calls to methods to set each option, then call [`open()`],
+/// passing the path of the file you're trying to open. This will give you a
 /// [`io::Result`][result] with a [`File`][file] inside that you can further
 /// operate on.
 ///
+/// [`new()`]: struct.OpenOptions.html#method.new
+/// [`open()`]: struct.OpenOptions.html#method.open
 /// [result]: ../io/type.Result.html
 /// [file]: struct.File.html
 ///
@@ -129,17 +146,19 @@ pub struct OpenOptions(fs_imp::OpenOptions);
 
 /// Representation of the various permissions on a file.
 ///
-/// This module only currently provides one bit of information, `readonly`,
+/// This module only currently provides one bit of information, [`readonly`],
 /// which is exposed on all currently supported platforms. Unix-specific
 /// functionality, such as mode bits, is available through the
 /// `os::unix::PermissionsExt` trait.
+///
+/// [`readonly`]: struct.Permissions.html#method.readonly
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Permissions(fs_imp::FilePermissions);
 
 /// An structure representing a type of file with accessors for each file type.
 #[stable(feature = "file_type", since = "1.1.0")]
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType(fs_imp::FileType);
 
 /// A builder used to create directories in various manners.
@@ -154,12 +173,14 @@ pub struct DirBuilder {
 impl File {
     /// Attempts to open a file in read-only mode.
     ///
-    /// See the `OpenOptions::open` method for more details.
+    /// See the [`OpenOptions::open`] method for more details.
     ///
     /// # Errors
     ///
     /// This function will return an error if `path` does not already exist.
-    /// Other errors may also be returned according to `OpenOptions::open`.
+    /// Other errors may also be returned according to [`OpenOptions::open`].
+    ///
+    /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
     ///
     /// # Examples
     ///
@@ -181,7 +202,9 @@ impl File {
     /// This function will create a file if it does not exist,
     /// and will truncate it if it does.
     ///
-    /// See the `OpenOptions::open` function for more details.
+    /// See the [`OpenOptions::open`] function for more details.
+    ///
+    /// [`OpenOptions::open`]: struct.OpenOptions.html#method.open
     ///
     /// # Examples
     ///
@@ -222,7 +245,7 @@ impl File {
         self.inner.fsync()
     }
 
-    /// This function is similar to `sync_all`, except that it may not
+    /// This function is similar to [`sync_all`], except that it may not
     /// synchronize file metadata to the filesystem.
     ///
     /// This is intended for use cases that must synchronize content, but don't
@@ -230,7 +253,9 @@ impl File {
     /// operations.
     ///
     /// Note that some platforms may simply implement this in terms of
-    /// `sync_all`.
+    /// [`sync_all`].
+    ///
+    /// [`sync_all`]: struct.File.html#method.sync_all
     ///
     /// # Examples
     ///
@@ -302,6 +327,18 @@ impl File {
     /// The returned `File` is a reference to the same state that this object
     /// references. Both handles will read and write with the same cursor
     /// position.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut f = try!(File::open("foo.txt"));
+    /// let file_copy = try!(f.try_clone());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_try_clone", since = "1.9.0")]
     pub fn try_clone(&self) -> io::Result<File> {
         Ok(File {
@@ -510,7 +547,7 @@ impl OpenOptions {
     /// No file is allowed to exist at the target location, also no (dangling)
     /// symlink.
     ///
-    /// This option is useful because it as atomic. Otherwise between checking
+    /// This option is useful because it is atomic. Otherwise between checking
     /// whether a file exists and creating a new one, the file may have been
     /// created by another process (a TOCTOU race condition / attack).
     ///
@@ -657,7 +694,7 @@ impl Metadata {
     ///
     /// This field may not be available on all platforms, and will return an
     /// `Err` on platforms where it is not available.
-    #[unstable(feature = "fs_time", issue = "31399")]
+    #[stable(feature = "fs_time", since = "1.10.0")]
     pub fn modified(&self) -> io::Result<SystemTime> {
         self.0.modified().map(FromInner::from_inner)
     }
@@ -675,7 +712,7 @@ impl Metadata {
     ///
     /// This field may not be available on all platforms, and will return an
     /// `Err` on platforms where it is not available.
-    #[unstable(feature = "fs_time", issue = "31399")]
+    #[stable(feature = "fs_time", since = "1.10.0")]
     pub fn accessed(&self) -> io::Result<SystemTime> {
         self.0.accessed().map(FromInner::from_inner)
     }
@@ -689,7 +726,7 @@ impl Metadata {
     ///
     /// This field may not be available on all platforms, and will return an
     /// `Err` on platforms where it is not available.
-    #[unstable(feature = "fs_time", issue = "31399")]
+    #[stable(feature = "fs_time", since = "1.10.0")]
     pub fn created(&self) -> io::Result<SystemTime> {
         self.0.created().map(FromInner::from_inner)
     }
@@ -789,8 +826,8 @@ impl Iterator for ReadDir {
 impl DirEntry {
     /// Returns the full path to the file that this entry represents.
     ///
-    /// The full path is created by joining the original path to `read_dir` or
-    /// `walk_dir` with the filename of this entry.
+    /// The full path is created by joining the original path to `read_dir`
+    /// with the filename of this entry.
     ///
     /// # Examples
     ///
@@ -827,6 +864,26 @@ impl DirEntry {
     /// On Windows this function is cheap to call (no extra system calls
     /// needed), but on Unix platforms this function is the equivalent of
     /// calling `symlink_metadata` on the path.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    ///
+    /// if let Ok(entries) = fs::read_dir(".") {
+    ///     for entry in entries {
+    ///         if let Ok(entry) = entry {
+    ///             // Here, `entry` is a `DirEntry`.
+    ///             if let Ok(metadata) = entry.metadata() {
+    ///                 // Now let's show our entry's permissions!
+    ///                 println!("{:?}: {:?}", entry.path(), metadata.permissions());
+    ///             } else {
+    ///                 println!("Couldn't get metadata for {:?}", entry.path());
+    ///             }
+    ///         }
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
     pub fn metadata(&self) -> io::Result<Metadata> {
         self.0.metadata().map(Metadata)
@@ -842,6 +899,26 @@ impl DirEntry {
     /// On Windows and most Unix platforms this function is free (no extra
     /// system calls needed), but some Unix platforms may require the equivalent
     /// call to `symlink_metadata` to learn about the target file type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    ///
+    /// if let Ok(entries) = fs::read_dir(".") {
+    ///     for entry in entries {
+    ///         if let Ok(entry) = entry {
+    ///             // Here, `entry` is a `DirEntry`.
+    ///             if let Ok(file_type) = entry.file_type() {
+    ///                 // Now let's show our entry's file type!
+    ///                 println!("{:?}: {:?}", entry.path(), file_type);
+    ///             } else {
+    ///                 println!("Couldn't get file type for {:?}", entry.path());
+    ///             }
+    ///         }
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
     pub fn file_type(&self) -> io::Result<FileType> {
         self.0.file_type().map(FileType)
@@ -849,6 +926,21 @@ impl DirEntry {
 
     /// Returns the bare file name of this directory entry without any other
     /// leading path component.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    ///
+    /// if let Ok(entries) = fs::read_dir(".") {
+    ///     for entry in entries {
+    ///         if let Ok(entry) = entry {
+    ///             // Here, `entry` is a `DirEntry`.
+    ///             println!("{:?}", entry.file_name());
+    ///         }
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
     pub fn file_name(&self) -> OsString {
         self.0.file_name()
@@ -1338,11 +1430,12 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// // one possible implementation of walking a directory only visiting files
 /// fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> {
-///     if try!(fs::metadata(dir)).is_dir() {
+///     if dir.is_dir() {
 ///         for entry in try!(fs::read_dir(dir)) {
 ///             let entry = try!(entry);
-///             if try!(fs::metadata(entry.path())).is_dir() {
-///                 try!(visit_dirs(&entry.path(), cb));
+///             let path = entry.path();
+///             if path.is_dir() {
+///                 try!(visit_dirs(&path, cb));
 ///             } else {
 ///                 cb(&entry);
 ///             }
@@ -1394,6 +1487,14 @@ pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions)
 impl DirBuilder {
     /// Creates a new set of options with default mode/security settings for all
     /// platforms and also non-recursive.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs::DirBuilder;
+    ///
+    /// let builder = DirBuilder::new();
+    /// ```
     #[stable(feature = "dir_builder", since = "1.6.0")]
     pub fn new() -> DirBuilder {
         DirBuilder {
@@ -1406,7 +1507,16 @@ impl DirBuilder {
     /// all parent directories if they do not exist with the same security and
     /// permissions settings.
     ///
-    /// This option defaults to `false`
+    /// This option defaults to `false`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs::DirBuilder;
+    ///
+    /// let mut builder = DirBuilder::new();
+    /// builder.recursive(true);
+    /// ```
     #[stable(feature = "dir_builder", since = "1.6.0")]
     pub fn recursive(&mut self, recursive: bool) -> &mut Self {
         self.recursive = recursive;
@@ -1543,7 +1653,7 @@ mod tests {
         let result = File::open(filename);
 
         if cfg!(unix) {
-            error!(result, "o such file or directory");
+            error!(result, "No such file or directory");
         }
         if cfg!(windows) {
             error!(result, "The system cannot find the file specified");
@@ -1558,7 +1668,7 @@ mod tests {
         let result = fs::remove_file(filename);
 
         if cfg!(unix) {
-            error!(result, "o such file or directory");
+            error!(result, "No such file or directory");
         }
         if cfg!(windows) {
             error!(result, "The system cannot find the file specified");
@@ -1768,11 +1878,20 @@ mod tests {
     }
 
     #[test]
+    fn file_create_new_already_exists_error() {
+        let tmpdir = tmpdir();
+        let file = &tmpdir.join("file_create_new_error_exists");
+        check!(fs::File::create(file));
+        let e = fs::OpenOptions::new().write(true).create_new(true).open(file).unwrap_err();
+        assert_eq!(e.kind(), ErrorKind::AlreadyExists);
+    }
+
+    #[test]
     fn mkdir_path_already_exists_error() {
         let tmpdir = tmpdir();
         let dir = &tmpdir.join("mkdir_error_twice");
         check!(fs::create_dir(dir));
-        let e = fs::create_dir(dir).err().unwrap();
+        let e = fs::create_dir(dir).unwrap_err();
         assert_eq!(e.kind(), ErrorKind::AlreadyExists);
     }
 
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 632ef3db804..a92ca95f4ee 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -1127,7 +1127,7 @@ mod tests {
             let mut writer = BufWriter::new(PanicWriter);
             let _ = writer.write(b"hello world");
             let _ = writer.flush();
-        }).join().err().unwrap();
+        }).join().unwrap_err();
 
         assert_eq!(WRITES.load(Ordering::SeqCst), 1);
     }
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index a1002fdb645..2d780559db1 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -230,6 +230,7 @@ impl<T> BufRead for Cursor<T> where T: AsRef<[u8]> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for Cursor<&'a mut [u8]> {
+    #[inline]
     fn write(&mut self, data: &[u8]) -> io::Result<usize> {
         let pos = cmp::min(self.pos, self.inner.len() as u64);
         let amt = (&mut self.inner[(pos as usize)..]).write(data)?;
@@ -269,6 +270,7 @@ impl Write for Cursor<Vec<u8>> {
 
 #[stable(feature = "cursor_box_slice", since = "1.5.0")]
 impl Write for Cursor<Box<[u8]>> {
+    #[inline]
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         let pos = cmp::min(self.pos, self.inner.len() as u64);
         let amt = (&mut self.inner[(pos as usize)..]).write(buf)?;
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index 9a605fc7bbf..05ae8ed5b0b 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -214,6 +214,30 @@ impl Error {
     }
 
     /// Creates a new instance of an `Error` from a particular OS error code.
+    ///
+    /// # Examples
+    ///
+    /// On Linux:
+    ///
+    /// ```
+    /// # if cfg!(target_os = "linux") {
+    /// use std::io;
+    ///
+    /// let error = io::Error::from_raw_os_error(98);
+    /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
+    /// # }
+    /// ```
+    ///
+    /// On Windows:
+    ///
+    /// ```
+    /// # if cfg!(windows) {
+    /// use std::io;
+    ///
+    /// let error = io::Error::from_raw_os_error(10048);
+    /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
+    /// # }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn from_raw_os_error(code: i32) -> Error {
         Error { repr: Repr::Os(code) }
@@ -350,7 +374,6 @@ mod test {
     use prelude::v1::*;
     use super::{Error, ErrorKind};
     use error;
-    use error::Error as error_Error;
     use fmt;
     use sys::os::error_string;
 
diff --git a/src/libstd/io/lazy.rs b/src/libstd/io/lazy.rs
index 65667f24dda..11551601207 100644
--- a/src/libstd/io/lazy.rs
+++ b/src/libstd/io/lazy.rs
@@ -12,11 +12,12 @@ use prelude::v1::*;
 
 use cell::Cell;
 use ptr;
-use sync::{StaticMutex, Arc};
+use sync::Arc;
 use sys_common;
+use sys_common::mutex::Mutex;
 
 pub struct Lazy<T> {
-    lock: StaticMutex,
+    lock: Mutex,
     ptr: Cell<*mut Arc<T>>,
     init: fn() -> Arc<T>,
 }
@@ -26,23 +27,25 @@ unsafe impl<T> Sync for Lazy<T> {}
 impl<T: Send + Sync + 'static> Lazy<T> {
     pub const fn new(init: fn() -> Arc<T>) -> Lazy<T> {
         Lazy {
-            lock: StaticMutex::new(),
+            lock: Mutex::new(),
             ptr: Cell::new(ptr::null_mut()),
             init: init
         }
     }
 
     pub fn get(&'static self) -> Option<Arc<T>> {
-        let _g = self.lock.lock();
-        let ptr = self.ptr.get();
         unsafe {
-            if ptr.is_null() {
+            self.lock.lock();
+            let ptr = self.ptr.get();
+            let ret = if ptr.is_null() {
                 Some(self.init())
             } else if ptr as usize == 1 {
                 None
             } else {
                 Some((*ptr).clone())
-            }
+            };
+            self.lock.unlock();
+            return ret
         }
     }
 
@@ -52,10 +55,10 @@ impl<T: Send + Sync + 'static> Lazy<T> {
         // the at exit handler). Otherwise we just return the freshly allocated
         // `Arc`.
         let registered = sys_common::at_exit(move || {
-            let g = self.lock.lock();
+            self.lock.lock();
             let ptr = self.ptr.get();
             self.ptr.set(1 as *mut _);
-            drop(g);
+            self.lock.unlock();
             drop(Box::from_raw(ptr))
         });
         let ret = (self.init)();
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index d914d143e70..d5b255ee573 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -182,11 +182,10 @@
 //!
 //! # fn foo() -> io::Result<()> {
 //! let f = try!(File::open("foo.txt"));
-//! let mut reader = BufReader::new(f);
+//! let reader = BufReader::new(f);
 //!
 //! for line in reader.lines() {
-//!     let line = try!(line);
-//!     println!("{}", line);
+//!     println!("{}", try!(line));
 //! }
 //!
 //! # Ok(())
@@ -195,7 +194,7 @@
 //!
 //! ## Functions
 //!
-//! There are a number of [functions][functions] that offer access to various
+//! There are a number of [functions][functions-list] that offer access to various
 //! features. For example, we can use three of these functions to copy everything
 //! from standard input to standard output:
 //!
@@ -208,7 +207,7 @@
 //! # }
 //! ```
 //!
-//! [functions]: #functions
+//! [functions-list]: #functions-1
 //!
 //! ## io::Result
 //!
@@ -1523,6 +1522,18 @@ impl<T: BufRead> BufRead for Take<T> {
     }
 }
 
+fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
+    let mut buf = [0];
+    loop {
+        return match reader.read(&mut buf) {
+            Ok(0) => None,
+            Ok(..) => Some(Ok(buf[0])),
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
+            Err(e) => Some(Err(e)),
+        };
+    }
+}
+
 /// An iterator over `u8` values of a reader.
 ///
 /// This struct is generally created by calling [`bytes()`][bytes] on a reader.
@@ -1539,12 +1550,7 @@ impl<R: Read> Iterator for Bytes<R> {
     type Item = Result<u8>;
 
     fn next(&mut self) -> Option<Result<u8>> {
-        let mut buf = [0];
-        match self.inner.read(&mut buf) {
-            Ok(0) => None,
-            Ok(..) => Some(Ok(buf[0])),
-            Err(e) => Some(Err(e)),
-        }
+        read_one_byte(&mut self.inner)
     }
 }
 
@@ -1580,11 +1586,10 @@ impl<R: Read> Iterator for Chars<R> {
     type Item = result::Result<char, CharsError>;
 
     fn next(&mut self) -> Option<result::Result<char, CharsError>> {
-        let mut buf = [0];
-        let first_byte = match self.inner.read(&mut buf) {
-            Ok(0) => return None,
-            Ok(..) => buf[0],
-            Err(e) => return Some(Err(CharsError::Other(e))),
+        let first_byte = match read_one_byte(&mut self.inner) {
+            None => return None,
+            Some(Ok(b)) => b,
+            Some(Err(e)) => return Some(Err(CharsError::Other(e))),
         };
         let width = core_str::utf8_char_width(first_byte);
         if width == 1 { return Some(Ok(first_byte as char)) }
@@ -1596,6 +1601,7 @@ impl<R: Read> Iterator for Chars<R> {
                 match self.inner.read(&mut buf[start..width]) {
                     Ok(0) => return Some(Err(CharsError::NotUtf8)),
                     Ok(n) => start += n,
+                    Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
                     Err(e) => return Some(Err(CharsError::Other(e))),
                 }
             }
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 2815c0163d6..c8b52fc0467 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -78,14 +78,11 @@ pub struct Empty { _priv: () }
 /// A slightly sad example of not reading anything into a buffer:
 ///
 /// ```
-/// use std::io;
-/// use std::io::Read;
+/// use std::io::{self, Read};
 ///
-/// # fn foo() -> io::Result<String> {
 /// let mut buffer = String::new();
-/// try!(io::empty().read_to_string(&mut buffer));
-/// # Ok(buffer)
-/// # }
+/// io::empty().read_to_string(&mut buffer).unwrap();
+/// assert!(buffer.is_empty());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn empty() -> Empty { Empty { _priv: () } }
@@ -113,6 +110,16 @@ pub struct Repeat { byte: u8 }
 ///
 /// All reads from this reader will succeed by filling the specified buffer with
 /// the given byte.
+///
+/// # Examples
+///
+/// ```
+/// use std::io::{self, Read};
+///
+/// let mut buffer = [0; 3];
+/// io::repeat(0b101).read_exact(&mut buffer).unwrap();
+/// assert_eq!(buffer, [0b101, 0b101, 0b101]);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
 
@@ -139,6 +146,16 @@ pub struct Sink { _priv: () }
 ///
 /// All calls to `write` on the returned instance will return `Ok(buf.len())`
 /// and the contents of the buffer will not be inspected.
+///
+/// # Examples
+///
+/// ```rust
+/// use std::io::{self, Write};
+///
+/// let buffer = vec![1, 2, 3, 5, 8];
+/// let num_bytes = io::sink().write(&buffer).unwrap();
+/// assert_eq!(num_bytes, 5);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn sink() -> Sink { Sink { _priv: () } }
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index e14a31453d3..d05a5a09614 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -210,6 +210,8 @@
        test(no_crate_inject, attr(deny(warnings))),
        test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
 
+#![needs_panic_runtime]
+
 #![feature(alloc)]
 #![feature(allow_internal_unstable)]
 #![feature(asm)]
@@ -245,6 +247,7 @@
 #![feature(on_unimplemented)]
 #![feature(oom)]
 #![feature(optin_builtin_traits)]
+#![feature(panic_unwind)]
 #![feature(placement_in_syntax)]
 #![feature(rand)]
 #![feature(raw)]
@@ -252,6 +255,7 @@
 #![feature(reflect_marker)]
 #![feature(rustc_attrs)]
 #![feature(shared)]
+#![feature(sip_hash_13)]
 #![feature(slice_bytes)]
 #![feature(slice_concat_ext)]
 #![feature(slice_patterns)]
@@ -270,6 +274,8 @@
 #![feature(vec_push_all)]
 #![feature(zero_one)]
 #![feature(question_mark)]
+#![feature(try_from)]
+#![feature(needs_panic_runtime)]
 
 // Issue# 30592: Systematically use alloc_system during stage0 since jemalloc
 // might be unavailable or disabled
@@ -300,6 +306,9 @@ extern crate alloc;
 extern crate rustc_unicode;
 extern crate libc;
 
+// We always need an unwinder currently for backtraces
+extern crate unwind;
+
 #[cfg(stage0)]
 extern crate alloc_system;
 
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index 39adda1066a..6f0f6ecab5b 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -17,9 +17,9 @@
 /// The entry point for panic of Rust threads.
 ///
 /// This macro is used to inject panic into a Rust thread, causing the thread to
-/// unwind and panic entirely. Each thread's panic can be reaped as the
-/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
-/// the value which is transmitted.
+/// panic entirely. Each thread's panic can be reaped as the `Box<Any>` type,
+/// and the single-argument form of the `panic!` macro will be the value which
+/// is transmitted.
 ///
 /// The multi-argument form of this macro panics with a string and has the
 /// `format!` syntax for building a string.
@@ -41,14 +41,14 @@ macro_rules! panic {
         panic!("explicit panic")
     });
     ($msg:expr) => ({
-        $crate::rt::begin_unwind($msg, {
+        $crate::rt::begin_panic($msg, {
             // static requires less code at runtime, more constant data
             static _FILE_LINE: (&'static str, u32) = (file!(), line!());
             &_FILE_LINE
         })
     });
     ($fmt:expr, $($arg:tt)+) => ({
-        $crate::rt::begin_unwind_fmt(format_args!($fmt, $($arg)+), {
+        $crate::rt::begin_panic_fmt(&format_args!($fmt, $($arg)+), {
             // The leading _'s are to avoid dead code warnings if this is
             // used inside a dead function. Just `#[allow(dead_code)]` is
             // insufficient, since the user may have
@@ -98,7 +98,9 @@ macro_rules! print {
     ($($arg:tt)*) => ($crate::io::_print(format_args!($($arg)*)));
 }
 
-/// Macro for printing to the standard output, with a newline.
+/// Macro for printing to the standard output, with a newline. On all
+/// platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
+/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
 ///
 /// Use the `format!` syntax to write data to the standard output.
 /// See `std::fmt` for more information.
@@ -276,7 +278,7 @@ pub mod builtin {
     /// // fn concat_idents!(new, fun, name) { } // not usable in this way!
     /// # }
     /// ```
-    #[stable(feature = "rust1", since = "1.0.0")]
+    #[unstable(feature = "concat_idents", issue = "29599")]
     #[macro_export]
     macro_rules! concat_idents {
         ($($e:ident),*) => ({ /* compiler built-in */ })
diff --git a/src/libstd/memchr.rs b/src/libstd/memchr.rs
index 1d97611eabb..a408b4378e1 100644
--- a/src/libstd/memchr.rs
+++ b/src/libstd/memchr.rs
@@ -239,7 +239,7 @@ mod fallback {
         text[..offset].iter().rposition(|elt| *elt == x)
     }
 
-    // test fallback implementations on all plattforms
+    // test fallback implementations on all platforms
     #[test]
     fn matches_one() {
         assert_eq!(Some(0), memchr(b'a', b"a"));
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index d510339f1c5..b93ca8277e6 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -344,6 +344,9 @@ impl hash::Hash for SocketAddrV6 {
 /// some other type (e.g. a string) just for it to be converted back to
 /// `SocketAddr` in constructor methods is pointless.
 ///
+/// Addresses returned by the operating system that are not IP addresses are
+/// silently ignored.
+///
 /// Some examples:
 ///
 /// ```no_run
@@ -448,12 +451,7 @@ impl ToSocketAddrs for (Ipv6Addr, u16) {
 
 fn resolve_socket_addr(s: &str, p: u16) -> io::Result<vec::IntoIter<SocketAddr>> {
     let ips = lookup_host(s)?;
-    let v: Vec<_> = ips.map(|a| {
-        a.map(|mut a| {
-            a.set_port(p);
-            a
-        })
-    }).collect()?;
+    let v: Vec<_> = ips.map(|mut a| { a.set_port(p); a }).collect();
     Ok(v.into_iter())
 }
 
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index adceee6d73e..2a8bd0c88be 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -59,6 +59,66 @@ pub enum Ipv6MulticastScope {
     Global
 }
 
+impl IpAddr {
+    /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
+    /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
+    /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
+    #[unstable(feature="ip", issue="27709",
+               reason="recently added and depends on unstable Ipv4Addr.is_unspecified()")]
+    pub fn is_unspecified(&self) -> bool {
+        match *self {
+            IpAddr::V4(ref a) => a.is_unspecified(),
+            IpAddr::V6(ref a) => a.is_unspecified(),
+        }
+    }
+
+    /// Returns true if this is a loopback address ([IPv4], [IPv6]).
+    /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
+    /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
+    #[unstable(feature="ip", reason="recently added", issue="27709")]
+    pub fn is_loopback(&self) -> bool {
+        match *self {
+            IpAddr::V4(ref a) => a.is_loopback(),
+            IpAddr::V6(ref a) => a.is_loopback(),
+        }
+    }
+
+    /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
+    /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
+    /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
+    #[unstable(feature="ip", issue="27709",
+               reason="recently added and depends on unstable Ip{v4,v6}Addr.is_global()")]
+    pub fn is_global(&self) -> bool {
+        match *self {
+            IpAddr::V4(ref a) => a.is_global(),
+            IpAddr::V6(ref a) => a.is_global(),
+        }
+    }
+
+    /// Returns true if this is a multicast address ([IPv4], [IPv6]).
+    /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
+    /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
+    #[unstable(feature="ip", reason="recently added", issue="27709")]
+    pub fn is_multicast(&self) -> bool {
+        match *self {
+            IpAddr::V4(ref a) => a.is_multicast(),
+            IpAddr::V6(ref a) => a.is_multicast(),
+        }
+    }
+
+    /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
+    /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
+    /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
+    #[unstable(feature="ip", issue="27709",
+               reason="recently added and depends on unstable Ipv6Addr.is_documentation()")]
+    pub fn is_documentation(&self) -> bool {
+        match *self {
+            IpAddr::V4(ref a) => a.is_documentation(),
+            IpAddr::V6(ref a) => a.is_documentation(),
+        }
+    }
+}
+
 impl Ipv4Addr {
     /// Creates a new IPv4 address from four eight-bit octets.
     ///
@@ -82,14 +142,19 @@ impl Ipv4Addr {
         [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
     }
 
-    /// Returns true for the special 'unspecified' address 0.0.0.0.
+    /// Returns true for the special 'unspecified' address (0.0.0.0).
+    ///
+    /// This property is defined in _UNIX Network Programming, Second Edition_,
+    /// W. Richard Stevens, p. 891; see also [ip7]
+    /// [ip7][http://man7.org/linux/man-pages/man7/ip.7.html]
     pub fn is_unspecified(&self) -> bool {
         self.inner.s_addr == 0
     }
 
     /// Returns true if this is a loopback address (127.0.0.0/8).
     ///
-    /// This property is defined by RFC 6890
+    /// This property is defined by [RFC 1122].
+    /// [RFC 1122]: https://tools.ietf.org/html/rfc1122
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_loopback(&self) -> bool {
         self.octets()[0] == 127
@@ -97,7 +162,8 @@ impl Ipv4Addr {
 
     /// Returns true if this is a private address.
     ///
-    /// The private address ranges are defined in RFC1918 and include:
+    /// The private address ranges are defined in [RFC 1918] and include:
+    /// [RFC 1918]: https://tools.ietf.org/html/rfc1918
     ///
     ///  - 10.0.0.0/8
     ///  - 172.16.0.0/12
@@ -114,7 +180,8 @@ impl Ipv4Addr {
 
     /// Returns true if the address is link-local (169.254.0.0/16).
     ///
-    /// This property is defined by RFC 6890
+    /// This property is defined by [RFC 3927].
+    /// [RFC 3927]: https://tools.ietf.org/html/rfc3927
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_link_local(&self) -> bool {
         self.octets()[0] == 169 && self.octets()[1] == 254
@@ -137,18 +204,20 @@ impl Ipv4Addr {
         !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified()
     }
 
-    /// Returns true if this is a multicast address.
+    /// Returns true if this is a multicast address (224.0.0.0/4).
     ///
     /// Multicast addresses have a most significant octet between 224 and 239,
-    /// and is defined by RFC 5771
+    /// and is defined by [RFC 5771].
+    /// [RFC 5771]: https://tools.ietf.org/html/rfc5771
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_multicast(&self) -> bool {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
-    /// Returns true if this is a broadcast address.
+    /// Returns true if this is a broadcast address (255.255.255.255).
     ///
-    /// A broadcast address has all octets set to 255 as defined in RFC 919.
+    /// A broadcast address has all octets set to 255 as defined in [RFC 919].
+    /// [RFC 919]: https://tools.ietf.org/html/rfc919
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_broadcast(&self) -> bool {
         self.octets()[0] == 255 && self.octets()[1] == 255 &&
@@ -157,7 +226,8 @@ impl Ipv4Addr {
 
     /// Returns true if this address is in a range designated for documentation.
     ///
-    /// This is defined in RFC 5737:
+    /// This is defined in [RFC 5737]:
+    /// [RFC 5737]: https://tools.ietf.org/html/rfc5737
     ///
     /// - 192.0.2.0/24 (TEST-NET-1)
     /// - 198.51.100.0/24 (TEST-NET-2)
@@ -251,7 +321,7 @@ impl PartialOrd for Ipv4Addr {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Ord for Ipv4Addr {
     fn cmp(&self, other: &Ipv4Addr) -> Ordering {
-        self.octets().cmp(&other.octets())
+        ntoh(self.inner.s_addr).cmp(&ntoh(other.inner.s_addr))
     }
 }
 
@@ -321,9 +391,10 @@ impl Ipv6Addr {
         ]
     }
 
-    /// Returns true for the special 'unspecified' address ::.
+    /// Returns true for the special 'unspecified' address (::).
     ///
-    /// This property is defined in RFC 6890.
+    /// This property is defined in [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_unspecified(&self) -> bool {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
@@ -331,7 +402,8 @@ impl Ipv6Addr {
 
     /// Returns true if this is a loopback address (::1).
     ///
-    /// This property is defined in RFC 6890.
+    /// This property is defined in [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_loopback(&self) -> bool {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
@@ -352,26 +424,33 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns true if this is a unique local address (IPv6).
+    /// Returns true if this is a unique local address (fc00::/7).
     ///
-    /// Unique local addresses are defined in RFC4193 and have the form fc00::/7.
+    /// This property is defined in [RFC 4193].
+    /// [RFC 4193]: https://tools.ietf.org/html/rfc4193
     pub fn is_unique_local(&self) -> bool {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
     /// Returns true if the address is unicast and link-local (fe80::/10).
+    ///
+    /// This property is defined in [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     pub fn is_unicast_link_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns true if this is a deprecated unicast site-local address (IPv6
-    /// fec0::/10).
+    /// Returns true if this is a deprecated unicast site-local address
+    /// (fec0::/10).
     pub fn is_unicast_site_local(&self) -> bool {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
 
     /// Returns true if this is an address reserved for documentation
-    /// This is defined to be 2001:db8::/32 in RFC RFC 3849
+    /// (2001:db8::/32).
+    ///
+    /// This property is defined in [RFC 3849].
+    /// [RFC 3849]: https://tools.ietf.org/html/rfc3849
     pub fn is_documentation(&self) -> bool {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
     }
@@ -411,10 +490,10 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns true if this is a multicast address.
+    /// Returns true if this is a multicast address (ff00::/8).
     ///
-    /// Multicast addresses have the form ff00::/8, and this property is defined
-    /// by RFC 3956.
+    /// This property is defined by [RFC 4291].
+    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     #[stable(since = "1.7.0", feature = "ip_17")]
     pub fn is_multicast(&self) -> bool {
         (self.segments()[0] & 0xff00) == 0xff00
@@ -742,6 +821,67 @@ mod tests {
     }
 
     #[test]
+    fn ip_properties() {
+        fn check4(octets: &[u8; 4], unspec: bool, loopback: bool,
+                  global: bool, multicast: bool, documentation: bool) {
+            let ip = IpAddr::V4(Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]));
+            assert_eq!(ip.is_unspecified(), unspec);
+            assert_eq!(ip.is_loopback(), loopback);
+            assert_eq!(ip.is_global(), global);
+            assert_eq!(ip.is_multicast(), multicast);
+            assert_eq!(ip.is_documentation(), documentation);
+        }
+
+        fn check6(str_addr: &str, unspec: bool, loopback: bool,
+                  global: bool, u_doc: bool, mcast: bool) {
+            let ip = IpAddr::V6(str_addr.parse().unwrap());
+            assert_eq!(ip.is_unspecified(), unspec);
+            assert_eq!(ip.is_loopback(), loopback);
+            assert_eq!(ip.is_global(), global);
+            assert_eq!(ip.is_documentation(), u_doc);
+            assert_eq!(ip.is_multicast(), mcast);
+        }
+
+        //     address                unspec loopbk global multicast doc
+        check4(&[0, 0, 0, 0],         true,  false, false,  false,   false);
+        check4(&[0, 0, 0, 1],         false, false, true,   false,   false);
+        check4(&[0, 1, 0, 0],         false, false, true,   false,   false);
+        check4(&[10, 9, 8, 7],        false, false, false,  false,   false);
+        check4(&[127, 1, 2, 3],       false, true,  false,  false,   false);
+        check4(&[172, 31, 254, 253],  false, false, false,  false,   false);
+        check4(&[169, 254, 253, 242], false, false, false,  false,   false);
+        check4(&[192, 0, 2, 183],     false, false, false,  false,   true);
+        check4(&[192, 1, 2, 183],     false, false, true,   false,   false);
+        check4(&[192, 168, 254, 253], false, false, false,  false,   false);
+        check4(&[198, 51, 100, 0],    false, false, false,  false,   true);
+        check4(&[203, 0, 113, 0],     false, false, false,  false,   true);
+        check4(&[203, 2, 113, 0],     false, false, true,   false,   false);
+        check4(&[224, 0, 0, 0],       false, false, true,   true,    false);
+        check4(&[239, 255, 255, 255], false, false, true,   true,    false);
+        check4(&[255, 255, 255, 255], false, false, false,  false,   false);
+
+        //     address                            unspec loopbk global doc    mcast
+        check6("::",                              true,  false, false, false, false);
+        check6("::1",                             false, true,  false, false, false);
+        check6("::0.0.0.2",                       false, false, true,  false, false);
+        check6("1::",                             false, false, true,  false, false);
+        check6("fc00::",                          false, false, false, false, false);
+        check6("fdff:ffff::",                     false, false, false, false, false);
+        check6("fe80:ffff::",                     false, false, false, false, false);
+        check6("febf:ffff::",                     false, false, false, false, false);
+        check6("fec0::",                          false, false, false, false, false);
+        check6("ff01::",                          false, false, false, false, true);
+        check6("ff02::",                          false, false, false, false, true);
+        check6("ff03::",                          false, false, false, false, true);
+        check6("ff04::",                          false, false, false, false, true);
+        check6("ff05::",                          false, false, false, false, true);
+        check6("ff08::",                          false, false, false, false, true);
+        check6("ff0e::",                          false, false, true,  false, true);
+        check6("2001:db8:85a3::8a2e:370:7334",    false, false, false, true,  false);
+        check6("102:304:506:708:90a:b0c:d0e:f10", false, false, true,  false, false);
+    }
+
+    #[test]
     fn ipv4_properties() {
         fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
                  private: bool, link_local: bool, global: bool,
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index 45070460282..ac13b23ebee 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -98,8 +98,8 @@ pub struct LookupHost(net_imp::LookupHost);
                                               addresses",
            issue = "27705")]
 impl Iterator for LookupHost {
-    type Item = io::Result<SocketAddr>;
-    fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> { self.0.next() }
 }
 
 /// Resolve the host specified by `host` as a number of `SocketAddr` instances.
@@ -107,6 +107,9 @@ impl Iterator for LookupHost {
 /// This method may perform a DNS query to resolve `host` and may also inspect
 /// system configuration to resolve the specified hostname.
 ///
+/// The returned iterator will skip over any unknown addresses returned by the
+/// operating system.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -116,7 +119,7 @@ impl Iterator for LookupHost {
 ///
 /// # fn foo() -> std::io::Result<()> {
 /// for host in try!(net::lookup_host("rust-lang.org")) {
-///     println!("found address: {}", try!(host));
+///     println!("found address: {}", host);
 /// }
 /// # Ok(())
 /// # }
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 94aa3d6b513..7a676c041ad 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -110,6 +110,7 @@ mod cmath {
         }
 
         #[inline]
+        #[allow(deprecated)]
         pub unsafe fn frexpf(x: c_float, value: &mut c_int) -> c_float {
             let (a, b) = f64::frexp(x as f64);
             *value = b as c_int;
@@ -117,6 +118,7 @@ mod cmath {
         }
 
         #[inline]
+        #[allow(deprecated)]
         pub unsafe fn ldexpf(x: c_float, n: c_int) -> c_float {
             f64::ldexp(x as f64, n as isize) as c_float
         }
@@ -217,7 +219,7 @@ impl f32 {
     /// // Values between `0` and `min` are Subnormal.
     /// assert!(!lower_than_min.is_normal());
     /// ```
-    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
@@ -265,7 +267,11 @@ impl f32 {
     /// [floating-point]: ../reference.html#machine-types
     #[unstable(feature = "float_extras", reason = "signature is undecided",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
+    #[allow(deprecated)]
     pub fn integer_decode(self) -> (u64, i16, i8) {
         num::Float::integer_decode(self)
     }
@@ -718,6 +724,9 @@ impl f32 {
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn ldexp(x: f32, exp: isize) -> f32 {
         unsafe { cmath::ldexpf(x, exp as c_int) }
@@ -747,6 +756,9 @@ impl f32 {
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn frexp(self) -> (f32, isize) {
         unsafe {
@@ -773,6 +785,9 @@ impl f32 {
     #[unstable(feature = "float_extras",
                reason = "unsure about its place in the world",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn next_after(self, other: f32) -> f32 {
         unsafe { cmath::nextafterf(self, other) }
@@ -829,6 +844,13 @@ impl f32 {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[rustc_deprecated(since = "1.10.0",
+                       reason = "you probably meant `(self - other).abs()`: \
+                                 this operation is `(self - other).max(0.0)` (also \
+                                 known as `fdimf` in C). If you truly need the positive \
+                                 difference, consider using that expression or the C function \
+                                 `fdimf`, depending on how you wish to handle NaN (please consider \
+                                 filing an issue describing your use-case too).")]
     pub fn abs_sub(self, other: f32) -> f32 {
         unsafe { cmath::fdimf(self, other) }
     }
@@ -916,12 +938,12 @@ impl f32 {
     /// Computes the tangent of a number (in radians).
     ///
     /// ```
-    /// use std::f64;
+    /// use std::f32;
     ///
-    /// let x = f64::consts::PI/4.0;
+    /// let x = f32::consts::PI / 4.0;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
-    /// assert!(abs_difference < 1e-10);
+    /// assert!(abs_difference <= f32::EPSILON);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -939,7 +961,7 @@ impl f32 {
     /// let f = f32::consts::PI / 2.0;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = f.sin().asin().abs_sub(f32::consts::PI / 2.0);
+    /// let abs_difference = (f.sin().asin() - f32::consts::PI / 2.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -959,7 +981,7 @@ impl f32 {
     /// let f = f32::consts::PI / 4.0;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = f.cos().acos().abs_sub(f32::consts::PI / 4.0);
+    /// let abs_difference = (f.cos().acos() - f32::consts::PI / 4.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -978,7 +1000,7 @@ impl f32 {
     /// let f = 1.0f32;
     ///
     /// // atan(tan(1))
-    /// let abs_difference = f.tan().atan().abs_sub(1.0);
+    /// let abs_difference = (f.tan().atan() - 1.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -1045,12 +1067,14 @@ impl f32 {
     /// number is close to zero.
     ///
     /// ```
-    /// let x = 7.0f64;
+    /// use std::f32;
+    ///
+    /// let x = 6.0f32;
     ///
-    /// // e^(ln(7)) - 1
-    /// let abs_difference = x.ln().exp_m1().abs_sub(6.0);
+    /// // e^(ln(6)) - 1
+    /// let abs_difference = (x.ln().exp_m1() - 5.0).abs();
     ///
-    /// assert!(abs_difference < 1e-10);
+    /// assert!(abs_difference <= f32::EPSILON);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1108,7 +1132,7 @@ impl f32 {
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
     /// let g = (e*e + 1.0)/(2.0*e);
-    /// let abs_difference = f.abs_sub(g);
+    /// let abs_difference = (f - g).abs();
     ///
     /// // Same result
     /// assert!(abs_difference <= f32::EPSILON);
@@ -1191,9 +1215,9 @@ impl f32 {
     /// let e = f32::consts::E;
     /// let f = e.tanh().atanh();
     ///
-    /// let abs_difference = f.abs_sub(e);
+    /// let abs_difference = (f - e).abs();
     ///
-    /// assert!(abs_difference <= f32::EPSILON);
+    /// assert!(abs_difference <= 1e-5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
@@ -1375,7 +1399,7 @@ mod tests {
     }
 
     #[test]
-    #[rustc_no_mir] // FIXME #27840 MIR NAN ends up negative.
+    #[allow(deprecated)]
     fn test_integer_decode() {
         assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
         assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
@@ -1384,7 +1408,11 @@ mod tests {
         assert_eq!((-0f32).integer_decode(), (0, -150, -1));
         assert_eq!(INFINITY.integer_decode(), (8388608, 105, 1));
         assert_eq!(NEG_INFINITY.integer_decode(), (8388608, 105, -1));
-        assert_eq!(NAN.integer_decode(), (12582912, 105, 1));
+
+        // Ignore the "sign" (quiet / signalling flag) of NAN.
+        // It can vary between runtime operations and LLVM folding.
+        let (nan_m, nan_e, _nan_s) = NAN.integer_decode();
+        assert_eq!((nan_m, nan_e), (12582912, 105));
     }
 
     #[test]
@@ -1699,6 +1727,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_ldexp() {
         let f1 = 2.0f32.powi(-123);
         let f2 = 2.0f32.powi(-111);
@@ -1719,6 +1748,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_frexp() {
         let f1 = 2.0f32.powi(-123);
         let f2 = 2.0f32.powi(-111);
@@ -1738,6 +1768,7 @@ mod tests {
     }
 
     #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    #[allow(deprecated)]
     fn test_frexp_nowin() {
         let inf: f32 = f32::INFINITY;
         let neg_inf: f32 = f32::NEG_INFINITY;
@@ -1748,24 +1779,6 @@ mod tests {
     }
 
     #[test]
-    fn test_abs_sub() {
-        assert_eq!((-1f32).abs_sub(1f32), 0f32);
-        assert_eq!(1f32.abs_sub(1f32), 0f32);
-        assert_eq!(1f32.abs_sub(0f32), 1f32);
-        assert_eq!(1f32.abs_sub(-1f32), 2f32);
-        assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
-        assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
-        assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
-        assert_eq!(0f32.abs_sub(INFINITY), 0f32);
-    }
-
-    #[test]
-    fn test_abs_sub_nowin() {
-        assert!(NAN.abs_sub(-1f32).is_nan());
-        assert!(1f32.abs_sub(NAN).is_nan());
-    }
-
-    #[test]
     fn test_asinh() {
         assert_eq!(0.0f32.asinh(), 0.0f32);
         assert_eq!((-0.0f32).asinh(), -0.0f32);
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 2beffb64d3d..67a1c302483 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -147,23 +147,23 @@ impl f64 {
     /// [subnormal][subnormal], or `NaN`.
     ///
     /// ```
-    /// use std::f32;
+    /// use std::f64;
     ///
-    /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f64
-    /// let max = f32::MAX;
-    /// let lower_than_min = 1.0e-40_f32;
-    /// let zero = 0.0f32;
+    /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
+    /// let max = f64::MAX;
+    /// let lower_than_min = 1.0e-308_f64;
+    /// let zero = 0.0f64;
     ///
     /// assert!(min.is_normal());
     /// assert!(max.is_normal());
     ///
     /// assert!(!zero.is_normal());
-    /// assert!(!f32::NAN.is_normal());
-    /// assert!(!f32::INFINITY.is_normal());
+    /// assert!(!f64::NAN.is_normal());
+    /// assert!(!f64::INFINITY.is_normal());
     /// // Values between `0` and `min` are Subnormal.
     /// assert!(!lower_than_min.is_normal());
     /// ```
-    /// [subnormal]: http://en.wikipedia.org/wiki/Denormal_number
+    /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_normal(self) -> bool { num::Float::is_normal(self) }
@@ -209,7 +209,11 @@ impl f64 {
     /// [floating-point]: ../reference.html#machine-types
     #[unstable(feature = "float_extras", reason = "signature is undecided",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
+    #[allow(deprecated)]
     pub fn integer_decode(self) -> (u64, i16, i8) { num::Float::integer_decode(self) }
 
     /// Returns the largest integer less than or equal to a number.
@@ -613,6 +617,9 @@ impl f64 {
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn ldexp(x: f64, exp: isize) -> f64 {
         unsafe { cmath::ldexp(x, exp as c_int) }
@@ -640,6 +647,9 @@ impl f64 {
     #[unstable(feature = "float_extras",
                reason = "pending integer conventions",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn frexp(self) -> (f64, isize) {
         unsafe {
@@ -655,15 +665,18 @@ impl f64 {
     /// ```
     /// #![feature(float_extras)]
     ///
-    /// let x = 1.0f32;
+    /// let x = 1.0f64;
     ///
-    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
+    /// let abs_diff = (x.next_after(2.0) - 1.0000000000000002220446049250313_f64).abs();
     ///
     /// assert!(abs_diff < 1e-10);
     /// ```
     #[unstable(feature = "float_extras",
                reason = "unsure about its place in the world",
                issue = "27752")]
+    #[rustc_deprecated(since = "1.11.0",
+                       reason = "never really came to fruition and easily \
+                                 implementable outside the standard library")]
     #[inline]
     pub fn next_after(self, other: f64) -> f64 {
         unsafe { cmath::nextafter(self, other) }
@@ -718,9 +731,16 @@ impl f64 {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn abs_sub(self, other: f64) -> f64 {
-        unsafe { cmath::fdim(self, other) }
-    }
+    #[rustc_deprecated(since = "1.10.0",
+                       reason = "you probably meant `(self - other).abs()`: \
+                                 this operation is `(self - other).max(0.0)` (also \
+                                 known as `fdim` in C). If you truly need the positive \
+                                 difference, consider using that expression or the C function \
+                                 `fdim`, depending on how you wish to handle NaN (please consider \
+                                 filing an issue describing your use-case too).")]
+     pub fn abs_sub(self, other: f64) -> f64 {
+         unsafe { cmath::fdim(self, other) }
+     }
 
     /// Takes the cubic root of a number.
     ///
@@ -1270,7 +1290,7 @@ mod tests {
     }
 
     #[test]
-    #[rustc_no_mir] // FIXME #27840 MIR NAN ends up negative.
+    #[allow(deprecated)]
     fn test_integer_decode() {
         assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
         assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
@@ -1279,7 +1299,11 @@ mod tests {
         assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
         assert_eq!(INFINITY.integer_decode(), (4503599627370496, 972, 1));
         assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
-        assert_eq!(NAN.integer_decode(), (6755399441055744, 972, 1));
+
+        // Ignore the "sign" (quiet / signalling flag) of NAN.
+        // It can vary between runtime operations and LLVM folding.
+        let (nan_m, nan_e, _nan_s) = NAN.integer_decode();
+        assert_eq!((nan_m, nan_e), (6755399441055744, 972));
     }
 
     #[test]
@@ -1594,6 +1618,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_ldexp() {
         let f1 = 2.0f64.powi(-123);
         let f2 = 2.0f64.powi(-111);
@@ -1614,6 +1639,7 @@ mod tests {
     }
 
     #[test]
+    #[allow(deprecated)]
     fn test_frexp() {
         let f1 = 2.0f64.powi(-123);
         let f2 = 2.0f64.powi(-111);
@@ -1633,6 +1659,7 @@ mod tests {
     }
 
     #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
+    #[allow(deprecated)]
     fn test_frexp_nowin() {
         let inf: f64 = INFINITY;
         let neg_inf: f64 = NEG_INFINITY;
@@ -1643,24 +1670,6 @@ mod tests {
     }
 
     #[test]
-    fn test_abs_sub() {
-        assert_eq!((-1f64).abs_sub(1f64), 0f64);
-        assert_eq!(1f64.abs_sub(1f64), 0f64);
-        assert_eq!(1f64.abs_sub(0f64), 1f64);
-        assert_eq!(1f64.abs_sub(-1f64), 2f64);
-        assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
-        assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
-        assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
-        assert_eq!(0f64.abs_sub(INFINITY), 0f64);
-    }
-
-    #[test]
-    fn test_abs_sub_nowin() {
-        assert!(NAN.abs_sub(-1f64).is_nan());
-        assert!(1f64.abs_sub(NAN).is_nan());
-    }
-
-    #[test]
     fn test_asinh() {
         assert_eq!(0.0f64.asinh(), 0.0f64);
         assert_eq!((-0.0f64).asinh(), -0.0f64);
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 1886b4fdf59..20804d62dfa 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -17,9 +17,10 @@
 #![allow(missing_docs)]
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(deprecated)]
 pub use core::num::{Zero, One};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
+pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::Wrapping;
 
@@ -46,7 +47,6 @@ pub fn test_num<T>(ten: T, two: T) where
 
 #[cfg(test)]
 mod tests {
-    use super::*;
     use u8;
     use u16;
     use u32;
@@ -198,15 +198,14 @@ mod tests {
 
     #[test]
     fn test_pow() {
-        fn naive_pow<T: Mul<Output=T> + One + Copy>(base: T, exp: usize) -> T {
-            let one: T = T::one();
+        fn naive_pow<T: Mul<Output=T> + Copy>(one: T, base: T, exp: usize) -> T {
             (0..exp).fold(one, |acc, _| acc * base)
         }
         macro_rules! assert_pow {
             (($num:expr, $exp:expr) => $expected:expr) => {{
                 let result = $num.pow($exp);
                 assert_eq!(result, $expected);
-                assert_eq!(result, naive_pow($num, $exp));
+                assert_eq!(result, naive_pow(1, $num, $exp));
             }}
         }
         assert_pow!((3u32,     0 ) => 1);
diff --git a/src/libstd/os/android/raw.rs b/src/libstd/os/android/raw.rs
index ce6e810592c..5e473a933a6 100644
--- a/src/libstd/os/android/raw.rs
+++ b/src/libstd/os/android/raw.rs
@@ -20,7 +20,8 @@
 
 use os::raw::c_long;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = c_long;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = c_long;
 
 #[doc(inline)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/src/libstd/os/bitrig/raw.rs b/src/libstd/os/bitrig/raw.rs
index 3fc3c5937f4..28958575eb2 100644
--- a/src/libstd/os/bitrig/raw.rs
+++ b/src/libstd/os/bitrig/raw.rs
@@ -31,7 +31,8 @@ use os::unix::raw::{uid_t, gid_t};
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/dragonfly/raw.rs b/src/libstd/os/dragonfly/raw.rs
index 83e0be0d158..5da2540ceee 100644
--- a/src/libstd/os/dragonfly/raw.rs
+++ b/src/libstd/os/dragonfly/raw.rs
@@ -30,7 +30,8 @@ use os::raw::c_long;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/emscripten/raw.rs b/src/libstd/os/emscripten/raw.rs
index 9da400a6913..bcd85f8e29a 100644
--- a/src/libstd/os/emscripten/raw.rs
+++ b/src/libstd/os/emscripten/raw.rs
@@ -25,7 +25,8 @@ use os::raw::{c_long, c_short, c_uint, c_ulong};
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = c_ulong;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = c_ulong;
 
 #[doc(inline)]
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64;
diff --git a/src/libstd/os/freebsd/raw.rs b/src/libstd/os/freebsd/raw.rs
index 989eef63d82..c755e5af8d9 100644
--- a/src/libstd/os/freebsd/raw.rs
+++ b/src/libstd/os/freebsd/raw.rs
@@ -30,7 +30,8 @@ use os::raw::c_long;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/ios/raw.rs b/src/libstd/os/ios/raw.rs
index 5a2de14b28b..8b34a932a17 100644
--- a/src/libstd/os/ios/raw.rs
+++ b/src/libstd/os/ios/raw.rs
@@ -29,7 +29,8 @@ use os::raw::c_long;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/linux/raw.rs b/src/libstd/os/linux/raw.rs
index 4113966841b..1be76961fea 100644
--- a/src/libstd/os/linux/raw.rs
+++ b/src/libstd/os/linux/raw.rs
@@ -23,7 +23,8 @@ use os::raw::c_ulong;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type dev_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type mode_t = u32;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = c_ulong;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = c_ulong;
 
 #[doc(inline)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/src/libstd/os/macos/raw.rs b/src/libstd/os/macos/raw.rs
index 2148670ccbd..8f9b29462c4 100644
--- a/src/libstd/os/macos/raw.rs
+++ b/src/libstd/os/macos/raw.rs
@@ -29,7 +29,8 @@ use os::raw::c_long;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/nacl/raw.rs b/src/libstd/os/nacl/raw.rs
index 9a10fbcc30b..3c3d4410a2a 100644
--- a/src/libstd/os/nacl/raw.rs
+++ b/src/libstd/os/nacl/raw.rs
@@ -30,7 +30,8 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = u64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Copy, Clone)]
diff --git a/src/libstd/os/netbsd/raw.rs b/src/libstd/os/netbsd/raw.rs
index bc30c1a7f48..9b2e037e59a 100644
--- a/src/libstd/os/netbsd/raw.rs
+++ b/src/libstd/os/netbsd/raw.rs
@@ -31,7 +31,8 @@ use os::unix::raw::{uid_t, gid_t};
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/openbsd/raw.rs b/src/libstd/os/openbsd/raw.rs
index 0e9a2128bc2..6142f036218 100644
--- a/src/libstd/os/openbsd/raw.rs
+++ b/src/libstd/os/openbsd/raw.rs
@@ -30,7 +30,8 @@ use os::raw::c_long;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/os/solaris/raw.rs b/src/libstd/os/solaris/raw.rs
index 6a75b36bd6b..b84fdba9ca2 100644
--- a/src/libstd/os/solaris/raw.rs
+++ b/src/libstd/os/solaris/raw.rs
@@ -31,7 +31,8 @@ use os::unix::raw::{uid_t, gid_t};
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type off_t = u64;
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type time_t = i64;
 
-#[unstable(feature = "pthread_t", issue = "29791")] pub type pthread_t = usize;
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
 
 #[repr(C)]
 #[derive(Clone)]
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index bbd89af01a7..ba18d15f5c4 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -16,37 +16,23 @@ use any::Any;
 use boxed::Box;
 use cell::UnsafeCell;
 use ops::{Deref, DerefMut};
+use panicking;
 use ptr::{Unique, Shared};
 use rc::Rc;
 use sync::{Arc, Mutex, RwLock};
-use sys_common::unwind;
 use thread::Result;
 
-#[unstable(feature = "panic_handler", issue = "30449")]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
 pub use panicking::{take_hook, set_hook, PanicInfo, Location};
 
-///
-#[rustc_deprecated(since = "1.9.0", reason = "renamed to set_hook")]
-#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
-pub fn set_handler<F>(handler: F) where F: Fn(&PanicInfo) + 'static + Sync + Send {
-    set_hook(Box::new(handler))
-}
-
-///
-#[rustc_deprecated(since = "1.9.0", reason = "renamed to take_hook")]
-#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
-pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
-    take_hook()
-}
-
 /// A marker trait which represents "panic safe" types in Rust.
 ///
 /// This trait is implemented by default for many types and behaves similarly in
 /// terms of inference of implementation to the `Send` and `Sync` traits. The
-/// purpose of this trait is to encode what types are safe to cross a `recover`
-/// boundary with no fear of panic safety.
+/// purpose of this trait is to encode what types are safe to cross a `catch_unwind`
+/// boundary with no fear of unwind safety.
 ///
-/// ## What is panic safety?
+/// ## What is unwind safety?
 ///
 /// In Rust a function can "return" early if it either panics or calls a
 /// function which transitively panics. This sort of control flow is not always
@@ -59,74 +45,66 @@ pub fn take_handler() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 ///
 /// Typically in Rust, it is difficult to perform step (2) because catching a
 /// panic involves either spawning a thread (which in turns makes it difficult
-/// to later witness broken invariants) or using the `recover` function in this
+/// to later witness broken invariants) or using the `catch_unwind` function in this
 /// module. Additionally, even if an invariant is witnessed, it typically isn't a
-/// problem in Rust because there's no uninitialized values (like in C or C++).
+/// problem in Rust because there are no uninitialized values (like in C or C++).
 ///
 /// It is possible, however, for **logical** invariants to be broken in Rust,
-/// which can end up causing behavioral bugs. Another key aspect of panic safety
+/// which can end up causing behavioral bugs. Another key aspect of unwind safety
 /// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
 /// memory unsafety.
 ///
-/// That was a bit of a whirlwind tour of panic safety, but for more information
-/// about panic safety and how it applies to Rust, see an [associated RFC][rfc].
+/// That was a bit of a whirlwind tour of unwind safety, but for more information
+/// about unwind safety and how it applies to Rust, see an [associated RFC][rfc].
 ///
 /// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
 ///
-/// ## What is `RecoverSafe`?
+/// ## What is `UnwindSafe`?
 ///
-/// Now that we've got an idea of what panic safety is in Rust, it's also
+/// Now that we've got an idea of what unwind safety is in Rust, it's also
 /// important to understand what this trait represents. As mentioned above, one
-/// way to witness broken invariants is through the `recover` function in this
+/// way to witness broken invariants is through the `catch_unwind` function in this
 /// module as it allows catching a panic and then re-using the environment of
 /// the closure.
 ///
-/// Simply put, a type `T` implements `RecoverSafe` if it cannot easily allow
-/// witnessing a broken invariant through the use of `recover` (catching a
+/// Simply put, a type `T` implements `UnwindSafe` if it cannot easily allow
+/// witnessing a broken invariant through the use of `catch_unwind` (catching a
 /// panic). This trait is a marker trait, so it is automatically implemented for
-/// many types, and it is also structurally composed (e.g. a struct is recover
-/// safe if all of its components are recover safe).
+/// many types, and it is also structurally composed (e.g. a struct is unwind
+/// safe if all of its components are unwind safe).
 ///
 /// Note, however, that this is not an unsafe trait, so there is not a succinct
 /// contract that this trait is providing. Instead it is intended as more of a
-/// "speed bump" to alert users of `recover` that broken invariants may be
+/// "speed bump" to alert users of `catch_unwind` that broken invariants may be
 /// witnessed and may need to be accounted for.
 ///
 /// ## Who implements `UnwindSafe`?
 ///
 /// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
-/// recover safe. The general idea is that any mutable state which can be shared
-/// across `recover` is not recover safe by default. This is because it is very
-/// easy to witness a broken invariant outside of `recover` as the data is
+/// unwind safe. The general idea is that any mutable state which can be shared
+/// across `catch_unwind` is not unwind safe by default. This is because it is very
+/// easy to witness a broken invariant outside of `catch_unwind` as the data is
 /// simply accessed as usual.
 ///
-/// Types like `&Mutex<T>`, however, are recover safe because they implement
+/// Types like `&Mutex<T>`, however, are unwind safe because they implement
 /// poisoning by default. They still allow witnessing a broken invariant, but
 /// they already provide their own "speed bumps" to do so.
 ///
 /// ## When should `UnwindSafe` be used?
 ///
 /// Is not intended that most types or functions need to worry about this trait.
-/// It is only used as a bound on the `recover` function and as mentioned above,
-/// the lack of `unsafe` means it is mostly an advisory. The `AssertRecoverSafe`
+/// It is only used as a bound on the `catch_unwind` function and as mentioned above,
+/// the lack of `unsafe` means it is mostly an advisory. The `AssertUnwindSafe`
 /// wrapper struct in this module can be used to force this trait to be
-/// implemented for any closed over variables passed to the `recover` function
+/// implemented for any closed over variables passed to the `catch_unwind` function
 /// (more on this below).
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
-                            across a recover boundary"]
+                            across an unwind boundary"]
 pub trait UnwindSafe {}
 
-/// Deprecated, renamed to UnwindSafe
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
-#[rustc_deprecated(reason = "renamed to `UnwindSafe`", since = "1.9.0")]
-pub trait RecoverSafe {}
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
-#[allow(deprecated)]
-impl<T: UnwindSafe> RecoverSafe for T {}
-
 /// A marker trait representing types where a shared reference is considered
-/// recover safe.
+/// unwind safe.
 ///
 /// This trait is namely not implemented by `UnsafeCell`, the root of all
 /// interior mutability.
@@ -136,23 +114,23 @@ impl<T: UnwindSafe> RecoverSafe for T {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 #[rustc_on_unimplemented = "the type {Self} contains interior mutability \
                             and a reference may not be safely transferrable \
-                            across a recover boundary"]
+                            across a catch_unwind boundary"]
 pub trait RefUnwindSafe {}
 
-/// A simple wrapper around a type to assert that it is panic safe.
+/// A simple wrapper around a type to assert that it is unwind safe.
 ///
-/// When using `recover` it may be the case that some of the closed over
-/// variables are not panic safe. For example if `&mut T` is captured the
-/// compiler will generate a warning indicating that it is not panic safe. It
+/// When using `catch_unwind` it may be the case that some of the closed over
+/// variables are not unwind safe. For example if `&mut T` is captured the
+/// compiler will generate a warning indicating that it is not unwind safe. It
 /// may not be the case, however, that this is actually a problem due to the
-/// specific usage of `recover` if panic safety is specifically taken into
+/// specific usage of `catch_unwind` if unwind safety is specifically taken into
 /// account. This wrapper struct is useful for a quick and lightweight
-/// annotation that a variable is indeed panic safe.
+/// annotation that a variable is indeed unwind safe.
 ///
 /// # Examples
 ///
 /// One way to use `AssertUnwindSafe` is to assert that the entire closure
-/// itself is recover safe, bypassing all checks for all variables:
+/// itself is unwind safe, bypassing all checks for all variables:
 ///
 /// ```
 /// use std::panic::{self, AssertUnwindSafe};
@@ -160,7 +138,7 @@ pub trait RefUnwindSafe {}
 /// let mut variable = 4;
 ///
 /// // This code will not compile because the closure captures `&mut variable`
-/// // which is not considered panic safe by default.
+/// // which is not considered unwind safe by default.
 ///
 /// // panic::catch_unwind(|| {
 /// //     variable += 3;
@@ -202,11 +180,6 @@ pub struct AssertUnwindSafe<T>(
     pub T
 );
 
-/// Deprecated, renamed to `AssertUnwindSafe`
-#[unstable(feature = "recover", issue = "27719")]
-#[rustc_deprecated(reason = "renamed to `AssertUnwindSafe`", since = "1.9.0")]
-pub struct AssertRecoverSafe<T>(pub T);
-
 // Implementations of the `UnwindSafe` trait:
 //
 // * By default everything is unwind safe
@@ -234,19 +207,16 @@ impl<T: ?Sized> UnwindSafe for Mutex<T> {}
 impl<T: ?Sized> UnwindSafe for RwLock<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> UnwindSafe for AssertUnwindSafe<T> {}
-#[unstable(feature = "recover", issue = "27719")]
-#[allow(deprecated)]
-impl<T> UnwindSafe for AssertRecoverSafe<T> {}
 
 // not covered via the Shared impl above b/c the inner contents use
-// Cell/AtomicUsize, but the usage here is recover safe so we can lift the
+// Cell/AtomicUsize, but the usage here is unwind safe so we can lift the
 // impl up one level to Arc/Rc itself
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Rc<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Arc<T> {}
 
-// Pretty simple implementations for the `RefRecoverSafe` marker trait,
+// Pretty simple implementations for the `RefUnwindSafe` marker trait,
 // basically just saying that this is a marker trait and `UnsafeCell` is the
 // only thing which doesn't implement it (which then transitively applies to
 // everything else).
@@ -256,9 +226,11 @@ impl RefUnwindSafe for .. {}
 impl<T: ?Sized> !RefUnwindSafe for UnsafeCell<T> {}
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> RefUnwindSafe for AssertUnwindSafe<T> {}
-#[unstable(feature = "recover", issue = "27719")]
-#[allow(deprecated)]
-impl<T> RefUnwindSafe for AssertRecoverSafe<T> {}
+
+#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
+impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
+#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
+impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}
 
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 impl<T> Deref for AssertUnwindSafe<T> {
@@ -285,53 +257,6 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertUnwindSafe<F> {
     }
 }
 
-#[allow(deprecated)]
-impl<T> AssertRecoverSafe<T> {
-    /// Creates a new `AssertRecoverSafe` wrapper around the provided type.
-    #[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
-    #[rustc_deprecated(reason = "the type's field is now public, construct it directly",
-                       since = "1.9.0")]
-    pub fn new(t: T) -> AssertRecoverSafe<T> {
-        AssertRecoverSafe(t)
-    }
-
-    /// Consumes the `AssertRecoverSafe`, returning the wrapped value.
-    #[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
-    #[rustc_deprecated(reason = "the type's field is now public, access it directly",
-                       since = "1.9.0")]
-    pub fn into_inner(self) -> T {
-        self.0
-    }
-}
-
-#[unstable(feature = "recover", issue = "27719")]
-#[allow(deprecated)]
-impl<T> Deref for AssertRecoverSafe<T> {
-    type Target = T;
-
-    fn deref(&self) -> &T {
-        &self.0
-    }
-}
-
-#[unstable(feature = "recover", issue = "27719")]
-#[allow(deprecated)]
-impl<T> DerefMut for AssertRecoverSafe<T> {
-    fn deref_mut(&mut self) -> &mut T {
-        &mut self.0
-    }
-}
-
-#[unstable(feature = "recover", issue = "27719")]
-#[allow(deprecated)]
-impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
-    type Output = R;
-
-    extern "rust-call" fn call_once(self, _args: ()) -> R {
-        (self.0)()
-    }
-}
-
 /// Invokes a closure, capturing the cause of an unwinding panic if one occurs.
 ///
 /// This function will return `Ok` with the closure's result if the closure
@@ -352,9 +277,9 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
 /// that all captured variables are safe to cross this boundary. The purpose of
 /// this bound is to encode the concept of [exception safety][rfc] in the type
 /// system. Most usage of this function should not need to worry about this
-/// bound as programs are naturally panic safe without `unsafe` code. If it
+/// bound as programs are naturally unwind safe without `unsafe` code. If it
 /// becomes a problem the associated `AssertUnwindSafe` wrapper type in this
-/// module can be used to quickly assert that the usage here is indeed exception
+/// module can be used to quickly assert that the usage here is indeed unwind
 /// safe.
 ///
 /// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
@@ -383,22 +308,12 @@ impl<R, F: FnOnce() -> R> FnOnce<()> for AssertRecoverSafe<F> {
 /// ```
 #[stable(feature = "catch_unwind", since = "1.9.0")]
 pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
-    let mut result = None;
     unsafe {
-        let result = &mut result;
-        unwind::try(move || *result = Some(f()))?
+        panicking::try(f)
     }
-    Ok(result.unwrap())
 }
 
-/// Deprecated, renamed to `catch_unwind`
-#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
-#[rustc_deprecated(reason = "renamed to `catch_unwind`", since = "1.9.0")]
-pub fn recover<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
-    catch_unwind(f)
-}
-
-/// Triggers a panic without invoking the panic handler.
+/// Triggers a panic without invoking the panic hook.
 ///
 /// This is designed to be used in conjunction with `catch_unwind` to, for
 /// example, carry a panic across a layer of C code.
@@ -425,12 +340,5 @@ pub fn recover<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
 /// ```
 #[stable(feature = "resume_unwind", since = "1.9.0")]
 pub fn resume_unwind(payload: Box<Any + Send>) -> ! {
-    unwind::rust_panic(payload)
-}
-
-/// Deprecated, use resume_unwind instead
-#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
-#[rustc_deprecated(reason = "renamed to `resume_unwind`", since = "1.9.0")]
-pub fn propagate(payload: Box<Any + Send>) -> ! {
-    resume_unwind(payload)
+    panicking::rust_panic(payload)
 }
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index fd6a15b0f69..d73e9542d21 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -8,14 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Implementation of various bits and pieces of the `panic!` macro and
+//! associated runtime pieces.
+//!
+//! Specifically, this module contains the implementation of:
+//!
+//! * Panic hooks
+//! * Executing a panic up to doing the actual implementation
+//! * Shims around "try"
+
 use prelude::v1::*;
 use io::prelude::*;
 
 use any::Any;
 use cell::Cell;
 use cell::RefCell;
+use fmt;
 use intrinsics;
-use sync::StaticRwLock;
+use mem;
+use raw;
+use sys_common::rwlock::RWLock;
 use sync::atomic::{AtomicBool, Ordering};
 use sys::stdio::Stderr;
 use sys_common::backtrace;
@@ -23,30 +35,51 @@ use sys_common::thread_info;
 use sys_common::util;
 use thread;
 
-thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
-
 thread_local! {
     pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
         RefCell::new(None)
     }
 }
 
+thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
+
+// Binary interface to the panic runtime that the standard library depends on.
+//
+// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
+// RFC 1513) to indicate that it requires some other crate tagged with
+// `#![panic_runtime]` to exist somewhere. Each panic runtime is intended to
+// implement these symbols (with the same signatures) so we can get matched up
+// to them.
+//
+// One day this may look a little less ad-hoc with the compiler helping out to
+// hook up these functions, but it is not this day!
+#[allow(improper_ctypes)]
+extern {
+    fn __rust_maybe_catch_panic(f: fn(*mut u8),
+                                data: *mut u8,
+                                data_ptr: *mut usize,
+                                vtable_ptr: *mut usize) -> u32;
+    #[unwind]
+    fn __rust_start_panic(data: usize, vtable: usize) -> u32;
+}
+
 #[derive(Copy, Clone)]
 enum Hook {
     Default,
     Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
 }
 
-static HOOK_LOCK: StaticRwLock = StaticRwLock::new();
+static HOOK_LOCK: RWLock = RWLock::new();
 static mut HOOK: Hook = Hook::Default;
 static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 
 /// Registers a custom panic hook, replacing any that was previously registered.
 ///
-/// The panic hook is invoked when a thread panics, but before it begins
-/// unwinding the stack. The default hook prints a message to standard error
-/// and generates a backtrace if requested, but this behavior can be customized
-/// with the `set_hook` and `take_hook` functions.
+/// The panic hook is invoked when a thread panics, but before the panic runtime
+/// is invoked. As such, the hook will run with both the aborting and unwinding
+/// runtimes. The default hook prints a message to standard error and generates
+/// a backtrace if requested, but this behavior can be customized with the
+/// `set_hook` and `take_hook` functions.
 ///
 /// The hook is provided with a `PanicInfo` struct which contains information
 /// about the origin of the panic, including the payload passed to `panic!` and
@@ -57,17 +90,17 @@ static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 /// # Panics
 ///
 /// Panics if called from a panicking thread.
-#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
 pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
     if thread::panicking() {
         panic!("cannot modify the panic hook from a panicking thread");
     }
 
     unsafe {
-        let lock = HOOK_LOCK.write();
+        HOOK_LOCK.write();
         let old_hook = HOOK;
         HOOK = Hook::Custom(Box::into_raw(hook));
-        drop(lock);
+        HOOK_LOCK.write_unlock();
 
         if let Hook::Custom(ptr) = old_hook {
             Box::from_raw(ptr);
@@ -82,17 +115,17 @@ pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
 /// # Panics
 ///
 /// Panics if called from a panicking thread.
-#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
 pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
     if thread::panicking() {
         panic!("cannot modify the panic hook from a panicking thread");
     }
 
     unsafe {
-        let lock = HOOK_LOCK.write();
+        HOOK_LOCK.write();
         let hook = HOOK;
         HOOK = Hook::Default;
-        drop(lock);
+        HOOK_LOCK.write_unlock();
 
         match hook {
             Hook::Default => Box::new(default_hook),
@@ -102,7 +135,7 @@ pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 }
 
 /// A struct providing information about a panic.
-#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
 pub struct PanicInfo<'a> {
     payload: &'a (Any + Send),
     location: Location<'a>,
@@ -112,7 +145,7 @@ impl<'a> PanicInfo<'a> {
     /// Returns the payload associated with the panic.
     ///
     /// This will commonly, but not always, be a `&'static str` or `String`.
-    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
     pub fn payload(&self) -> &(Any + Send) {
         self.payload
     }
@@ -122,14 +155,14 @@ impl<'a> PanicInfo<'a> {
     ///
     /// This method will currently always return `Some`, but this may change
     /// in future versions.
-    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
     pub fn location(&self) -> Option<&Location> {
         Some(&self.location)
     }
 }
 
 /// A struct containing information about the location of a panic.
-#[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+#[stable(feature = "panic_hooks", since = "1.10.0")]
 pub struct Location<'a> {
     file: &'a str,
     line: u32,
@@ -137,20 +170,20 @@ pub struct Location<'a> {
 
 impl<'a> Location<'a> {
     /// Returns the name of the source file from which the panic originated.
-    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
     pub fn file(&self) -> &str {
         self.file
     }
 
     /// Returns the line number from which the panic originated.
-    #[unstable(feature = "panic_handler", reason = "awaiting feedback", issue = "30449")]
+    #[stable(feature = "panic_hooks", since = "1.10.0")]
     pub fn line(&self) -> u32 {
         self.line
     }
 }
 
 fn default_hook(info: &PanicInfo) {
-    let panics = PANIC_COUNT.with(|s| s.get());
+    let panics = PANIC_COUNT.with(|c| c.get());
 
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
@@ -195,41 +228,152 @@ fn default_hook(info: &PanicInfo) {
     }
 }
 
-pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
-    let panics = PANIC_COUNT.with(|s| {
-        let count = s.get() + 1;
-        s.set(count);
-        count
+/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
+pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
+    let mut slot = None;
+    let mut f = Some(f);
+    let ret = PANIC_COUNT.with(|s| {
+        let prev = s.get();
+        s.set(0);
+
+        let mut to_run = || {
+            slot = Some(f.take().unwrap()());
+        };
+        let fnptr = get_call(&mut to_run);
+        let dataptr = &mut to_run as *mut _ as *mut u8;
+        let mut any_data = 0;
+        let mut any_vtable = 0;
+        let fnptr = mem::transmute::<fn(&mut _), fn(*mut u8)>(fnptr);
+        let r = __rust_maybe_catch_panic(fnptr,
+                                         dataptr,
+                                         &mut any_data,
+                                         &mut any_vtable);
+        s.set(prev);
+
+        if r == 0 {
+            Ok(())
+        } else {
+            Err(mem::transmute(raw::TraitObject {
+                data: any_data as *mut _,
+                vtable: any_vtable as *mut _,
+            }))
+        }
+    });
+
+    return ret.map(|()| {
+        slot.take().unwrap()
     });
 
-    // If this is the third nested call, on_panic triggered the last panic,
-    // otherwise the double-panic check would have aborted the process.
-    // Even if it is likely that on_panic was unable to log the backtrace,
-    // abort immediately to avoid infinite recursion, so that attaching a
-    // debugger provides a useable stacktrace.
-    if panics >= 3 {
+    fn get_call<F: FnMut()>(_: &mut F) -> fn(&mut F) {
+        call
+    }
+
+    fn call<F: FnMut()>(f: &mut F) {
+        f()
+    }
+}
+
+/// Determines whether the current thread is unwinding because of panic.
+pub fn panicking() -> bool {
+    PANIC_COUNT.with(|c| c.get() != 0)
+}
+
+/// Entry point of panic from the libcore crate.
+#[cfg(not(test))]
+#[lang = "panic_fmt"]
+#[unwind]
+pub extern fn rust_begin_panic(msg: fmt::Arguments,
+                               file: &'static str,
+                               line: u32) -> ! {
+    begin_panic_fmt(&msg, &(file, line))
+}
+
+/// The entry point for panicking with a formatted message.
+///
+/// This is designed to reduce the amount of code required at the call
+/// site as much as possible (so that `panic!()` has as low an impact
+/// on (e.g.) the inlining of other functions as possible), by moving
+/// the actual formatting into this shared place.
+#[unstable(feature = "libstd_sys_internals",
+           reason = "used by the panic! macro",
+           issue = "0")]
+#[inline(never)] #[cold]
+pub fn begin_panic_fmt(msg: &fmt::Arguments,
+                       file_line: &(&'static str, u32)) -> ! {
+    use fmt::Write;
+
+    // We do two allocations here, unfortunately. But (a) they're
+    // required with the current scheme, and (b) we don't handle
+    // panic + OOM properly anyway (see comment in begin_panic
+    // below).
+
+    let mut s = String::new();
+    let _ = s.write_fmt(*msg);
+    begin_panic(s, file_line)
+}
+
+/// This is the entry point of panicking for panic!() and assert!().
+#[unstable(feature = "libstd_sys_internals",
+           reason = "used by the panic! macro",
+           issue = "0")]
+#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
+pub fn begin_panic<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
+    // Note that this should be the only allocation performed in this code path.
+    // Currently this means that panic!() on OOM will invoke this code path,
+    // but then again we're not really ready for panic on OOM anyway. If
+    // we do start doing this, then we should propagate this allocation to
+    // be performed in the parent of this thread instead of the thread that's
+    // panicking.
+
+    rust_panic_with_hook(Box::new(msg), file_line)
+}
+
+/// Executes the primary logic for a panic, including checking for recursive
+/// panics and panic hooks.
+///
+/// This is the entry point or panics from libcore, formatted panics, and
+/// `Box<Any>` panics. Here we'll verify that we're not panicking recursively,
+/// run panic hooks, and then delegate to the actual implementation of panics.
+#[inline(never)]
+#[cold]
+fn rust_panic_with_hook(msg: Box<Any + Send>,
+                        file_line: &(&'static str, u32)) -> ! {
+    let (file, line) = *file_line;
+
+    let panics = PANIC_COUNT.with(|c| {
+        let prev = c.get();
+        c.set(prev + 1);
+        prev
+    });
+
+    // If this is the third nested call (e.g. panics == 2, this is 0-indexed),
+    // the panic hook probably triggered the last panic, otherwise the
+    // double-panic check would have aborted the process. In this case abort the
+    // process real quickly as we don't want to try calling it again as it'll
+    // probably just panic again.
+    if panics > 1 {
         util::dumb_print(format_args!("thread panicked while processing \
                                        panic. aborting.\n"));
         unsafe { intrinsics::abort() }
     }
 
-    let info = PanicInfo {
-        payload: obj,
-        location: Location {
-            file: file,
-            line: line,
-        },
-    };
-
     unsafe {
-        let _lock = HOOK_LOCK.read();
+        let info = PanicInfo {
+            payload: &*msg,
+            location: Location {
+                file: file,
+                line: line,
+            },
+        };
+        HOOK_LOCK.read();
         match HOOK {
             Hook::Default => default_hook(&info),
             Hook::Custom(ptr) => (*ptr)(&info),
         }
+        HOOK_LOCK.read_unlock();
     }
 
-    if panics >= 2 {
+    if panics > 0 {
         // If a thread panics while it's already unwinding then we
         // have limited options. Currently our preference is to
         // just abort. In the future we may consider resuming
@@ -238,4 +382,17 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
                                        aborting.\n"));
         unsafe { intrinsics::abort() }
     }
+
+    rust_panic(msg)
+}
+
+/// A private no-mangle function on which to slap yer breakpoints.
+#[no_mangle]
+#[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints
+pub fn rust_panic(msg: Box<Any + Send>) -> ! {
+    let code = unsafe {
+        let obj = mem::transmute::<_, raw::TraitObject>(msg);
+        __rust_start_panic(obj.data as usize, obj.vtable as usize)
+    };
+    rtabort!("failed to initiate panic, error {}", code)
 }
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index f413bed86a8..2d19561139b 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -525,6 +525,26 @@ impl<'a> Hash for PrefixComponent<'a> {
 ///
 /// See the module documentation for an in-depth explanation of components and
 /// their role in the API.
+///
+/// This `enum` is created from iterating over the [`path::Components`]
+/// `struct`.
+///
+/// # Examples
+///
+/// ```rust
+/// use std::path::{Component, Path};
+///
+/// let path = Path::new("/tmp/foo/bar.txt");
+/// let components = path.components().collect::<Vec<_>>();
+/// assert_eq!(&components, &[
+///     Component::RootDir,
+///     Component::Normal("tmp".as_ref()),
+///     Component::Normal("foo".as_ref()),
+///     Component::Normal("bar.txt".as_ref()),
+/// ]);
+/// ```
+///
+/// [`path::Components`]: struct.Components.html
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Component<'a> {
@@ -579,6 +599,8 @@ impl<'a> AsRef<OsStr> for Component<'a> {
 /// See the module documentation for an in-depth explanation of components and
 /// their role in the API.
 ///
+/// This `struct` is created by the [`path::Path::components`] method.
+///
 /// # Examples
 ///
 /// ```
@@ -590,6 +612,8 @@ impl<'a> AsRef<OsStr> for Component<'a> {
 ///     println!("{:?}", component);
 /// }
 /// ```
+///
+/// [`path::Path::components`]: struct.Path.html#method.components
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Components<'a> {
@@ -1033,7 +1057,6 @@ impl PathBuf {
         self._push(path.as_ref())
     }
 
-    #[allow(deprecated)]
     fn _push(&mut self, path: &Path) {
         // in general, a separator is needed if the rightmost byte is not a separator
         let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
@@ -1419,8 +1442,7 @@ impl Path {
     /// `is_absolute` and `has_root` are equivalent.
     ///
     /// * On Windows, a path is absolute if it has a prefix and starts with the
-    /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not. In
-    /// other words, `path.is_absolute() == path.prefix().is_some() && path.has_root()`.
+    /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not.
     ///
     /// # Examples
     ///
@@ -1507,8 +1529,7 @@ impl Path {
 
     /// The final component of the path, if it is a normal file.
     ///
-    /// If the path terminates in `.`, `..`, or consists solely of a root of
-    /// prefix, `file_name` will return `None`.
+    /// If the path terminates in `..`, `file_name` will return `None`.
     ///
     /// # Examples
     ///
@@ -1521,6 +1542,17 @@ impl Path {
     ///
     /// assert_eq!(Some(os_str), path.file_name());
     /// ```
+    ///
+    /// # Other examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    /// use std::ffi::OsStr;
+    ///
+    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.").file_name());
+    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.//").file_name());
+    /// assert_eq!(None, Path::new("foo.txt/..").file_name());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_name(&self) -> Option<&OsStr> {
         self.components().next_back().and_then(|p| {
@@ -1781,7 +1813,9 @@ impl Path {
     /// This function will traverse symbolic links to query information about the
     /// destination file.
     ///
-    /// This is an alias to `fs::metadata`.
+    /// This is an alias to [`fs::metadata`].
+    ///
+    /// [`fs::metadata`]: ../fs/fn.metadata.html
     #[stable(feature = "path_ext", since = "1.5.0")]
     pub fn metadata(&self) -> io::Result<fs::Metadata> {
         fs::metadata(self)
@@ -1789,7 +1823,9 @@ impl Path {
 
     /// Query the metadata about a file without following symlinks.
     ///
-    /// This is an alias to `fs::symlink_metadata`.
+    /// This is an alias to [`fs::symlink_metadata`].
+    ///
+    /// [`fs::symlink_metadata`]: ../fs/fn.symlink_metadata.html
     #[stable(feature = "path_ext", since = "1.5.0")]
     pub fn symlink_metadata(&self) -> io::Result<fs::Metadata> {
         fs::symlink_metadata(self)
@@ -1798,7 +1834,9 @@ impl Path {
     /// Returns the canonical form of the path with all intermediate components
     /// normalized and symbolic links resolved.
     ///
-    /// This is an alias to `fs::canonicalize`.
+    /// This is an alias to [`fs::canonicalize`].
+    ///
+    /// [`fs::canonicalize`]: ../fs/fn.canonicalize.html
     #[stable(feature = "path_ext", since = "1.5.0")]
     pub fn canonicalize(&self) -> io::Result<PathBuf> {
         fs::canonicalize(self)
@@ -1806,7 +1844,9 @@ impl Path {
 
     /// Reads a symbolic link, returning the file that the link points to.
     ///
-    /// This is an alias to `fs::read_link`.
+    /// This is an alias to [`fs::read_link`].
+    ///
+    /// [`fs::read_link`]: ../fs/fn.read_link.html
     #[stable(feature = "path_ext", since = "1.5.0")]
     pub fn read_link(&self) -> io::Result<PathBuf> {
         fs::read_link(self)
@@ -1817,7 +1857,9 @@ impl Path {
     /// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
     /// be encountered after an iterator is initially constructed.
     ///
-    /// This is an alias to `fs::read_dir`.
+    /// This is an alias to [`fs::read_dir`].
+    ///
+    /// [`fs::read_dir`]: ../fs/fn.read_dir.html
     #[stable(feature = "path_ext", since = "1.5.0")]
     pub fn read_dir(&self) -> io::Result<fs::ReadDir> {
         fs::read_dir(self)
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index e083605a2ac..de891ea8918 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -28,7 +28,7 @@
 /// ```
 ///
 /// [`assert!`]: macro.assert!.html
-/// [`if` conditionals]: ../book/if.html
+/// [`if`]: ../book/if.html
 /// [`BitAnd`]: ops/trait.BitAnd.html
 /// [`BitOr`]: ops/trait.BitOr.html
 /// [`Not`]: ops/trait.Not.html
@@ -490,9 +490,6 @@ mod prim_tuple { }
 ///
 /// *[See also the `std::f32` module](f32/index.html).*
 ///
-/// However, please note that examples are shared between the `f64` and `f32`
-/// primitive types. So it's normal if you see usage of `f64` in there.
-///
 mod prim_f32 { }
 
 #[doc(primitive = "f64")]
@@ -501,9 +498,6 @@ mod prim_f32 { }
 ///
 /// *[See also the `std::f64` module](f64/index.html).*
 ///
-/// However, please note that examples are shared between the `f64` and `f32`
-/// primitive types. So it's normal if you see usage of `f32` in there.
-///
 mod prim_f64 { }
 
 #[doc(primitive = "i8")]
@@ -512,6 +506,9 @@ mod prim_f64 { }
 ///
 /// *[See also the `std::i8` module](i8/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i64` in there.
+///
 mod prim_i8 { }
 
 #[doc(primitive = "i16")]
@@ -520,6 +517,9 @@ mod prim_i8 { }
 ///
 /// *[See also the `std::i16` module](i16/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i32` in there.
+///
 mod prim_i16 { }
 
 #[doc(primitive = "i32")]
@@ -528,6 +528,9 @@ mod prim_i16 { }
 ///
 /// *[See also the `std::i32` module](i32/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i16` in there.
+///
 mod prim_i32 { }
 
 #[doc(primitive = "i64")]
@@ -536,6 +539,9 @@ mod prim_i32 { }
 ///
 /// *[See also the `std::i64` module](i64/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `i8` in there.
+///
 mod prim_i64 { }
 
 #[doc(primitive = "u8")]
@@ -544,6 +550,9 @@ mod prim_i64 { }
 ///
 /// *[See also the `std::u8` module](u8/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u64` in there.
+///
 mod prim_u8 { }
 
 #[doc(primitive = "u16")]
@@ -552,6 +561,9 @@ mod prim_u8 { }
 ///
 /// *[See also the `std::u16` module](u16/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u32` in there.
+///
 mod prim_u16 { }
 
 #[doc(primitive = "u32")]
@@ -560,6 +572,9 @@ mod prim_u16 { }
 ///
 /// *[See also the `std::u32` module](u32/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u16` in there.
+///
 mod prim_u32 { }
 
 #[doc(primitive = "u64")]
@@ -568,6 +583,9 @@ mod prim_u32 { }
 ///
 /// *[See also the `std::u64` module](u64/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `u8` in there.
+///
 mod prim_u64 { }
 
 #[doc(primitive = "isize")]
@@ -576,6 +594,9 @@ mod prim_u64 { }
 ///
 /// *[See also the `std::isize` module](isize/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `usize` in there.
+///
 mod prim_isize { }
 
 #[doc(primitive = "usize")]
@@ -584,4 +605,7 @@ mod prim_isize { }
 ///
 /// *[See also the `std::usize` module](usize/index.html).*
 ///
+/// However, please note that examples are shared between primitive integer
+/// types. So it's normal if you see usage of types like `isize` in there.
+///
 mod prim_usize { }
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 1d2516a4c40..660c098d30b 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -27,8 +27,9 @@ use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// Representation of a running or exited child process.
 ///
 /// This structure is used to represent and manage child processes. A child
-/// process is created via the `Command` struct, which configures the spawning
-/// process and can itself be constructed using a builder-style interface.
+/// process is created via the [`Command`] struct, which configures the
+/// spawning process and can itself be constructed using a builder-style
+/// interface.
 ///
 /// # Examples
 ///
@@ -48,13 +49,18 @@ use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 ///
 /// # Note
 ///
-/// Take note that there is no implementation of
-/// [`Drop`](../../core/ops/trait.Drop.html) for child processes, so if you
-/// do not ensure the `Child` has exited then it will continue to run, even
-/// after the `Child` handle to the child process has gone out of scope.
+/// Take note that there is no implementation of [`Drop`] for child processes,
+/// so if you do not ensure the `Child` has exited then it will continue to
+/// run, even after the `Child` handle to the child process has gone out of
+/// scope.
 ///
-/// Calling `wait` (or other functions that wrap around it) will make the
-/// parent process wait until the child has actually exited before continuing.
+/// Calling [`wait`][`wait`] (or other functions that wrap around it) will make
+/// the parent process wait until the child has actually exited before
+/// continuing.
+///
+/// [`Command`]: struct.Command.html
+/// [`Drop`]: ../../core/ops/trait.Drop.html
+/// [`wait`]: #method.wait
 #[stable(feature = "process", since = "1.0.0")]
 pub struct Child {
     handle: imp::Process,
@@ -91,7 +97,11 @@ impl IntoInner<imp::Process> for Child {
     fn into_inner(self) -> imp::Process { self.handle }
 }
 
-/// A handle to a child process's stdin
+/// A handle to a child process's stdin. This struct is used in the [`stdin`]
+/// field on [`Child`].
+///
+/// [`Child`]: struct.Child.html
+/// [`stdin`]: struct.Child.html#structfield.stdin
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdin {
     inner: AnonPipe
@@ -122,7 +132,11 @@ impl FromInner<AnonPipe> for ChildStdin {
     }
 }
 
-/// A handle to a child process's stdout
+/// A handle to a child process's stdout. This struct is used in the [`stdout`]
+/// field on [`Child`].
+///
+/// [`Child`]: struct.Child.html
+/// [`stdout`]: struct.Child.html#structfield.stdout
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStdout {
     inner: AnonPipe
@@ -152,7 +166,11 @@ impl FromInner<AnonPipe> for ChildStdout {
     }
 }
 
-/// A handle to a child process's stderr
+/// A handle to a child process's stderr. This struct is used in the [`stderr`]
+/// field on [`Child`].
+///
+/// [`Child`]: struct.Child.html
+/// [`stderr`]: struct.Child.html#structfield.stderr
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ChildStderr {
     inner: AnonPipe
@@ -182,8 +200,10 @@ impl FromInner<AnonPipe> for ChildStderr {
     }
 }
 
-/// The `Command` type acts as a process builder, providing fine-grained control
-/// over how a new process should be spawned. A default configuration can be
+/// A process builder, providing fine-grained control
+/// over how a new process should be spawned.
+///
+/// A default configuration can be
 /// generated using `Command::new(program)`, where `program` gives a path to the
 /// program to be executed. Additional builder methods allow the configuration
 /// to be changed (for example, by adding arguments) prior to spawning:
@@ -195,7 +215,7 @@ impl FromInner<AnonPipe> for ChildStderr {
 ///                      .arg("-c")
 ///                      .arg("echo hello")
 ///                      .output()
-///                      .expect("failed to execute proces");
+///                      .expect("failed to execute process");
 ///
 /// let hello = output.stdout;
 /// ```
@@ -215,12 +235,38 @@ impl Command {
     ///
     /// Builder methods are provided to change these defaults and
     /// otherwise configure the process.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("sh")
+    ///         .spawn()
+    ///         .expect("sh command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
         Command { inner: imp::Command::new(program.as_ref()) }
     }
 
     /// Add an argument to pass to the program.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .arg("-l")
+    ///         .arg("-a")
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
         self.inner.arg(arg.as_ref());
@@ -228,6 +274,19 @@ impl Command {
     }
 
     /// Add multiple arguments to pass to the program.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .args(&["-l", "-a"])
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> &mut Command {
         for arg in args {
@@ -240,6 +299,19 @@ impl Command {
     ///
     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
     /// and case-sensitive on all other platforms.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .env("PATH", "/bin")
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
         where K: AsRef<OsStr>, V: AsRef<OsStr>
@@ -249,6 +321,19 @@ impl Command {
     }
 
     /// Removes an environment variable mapping.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .env_remove("PATH")
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
         self.inner.env_remove(key.as_ref());
@@ -256,6 +341,19 @@ impl Command {
     }
 
     /// Clears the entire environment map for the child process.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .env_clear()
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn env_clear(&mut self) -> &mut Command {
         self.inner.env_clear();
@@ -263,6 +361,19 @@ impl Command {
     }
 
     /// Sets the working directory for the child process.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .current_dir("/bin")
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
         self.inner.cwd(dir.as_ref().as_ref());
@@ -270,6 +381,19 @@ impl Command {
     }
 
     /// Configuration for the child process's stdin handle (file descriptor 0).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::{Command, Stdio};
+    ///
+    /// Command::new("ls")
+    ///         .stdin(Stdio::null())
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn stdin(&mut self, cfg: Stdio) -> &mut Command {
         self.inner.stdin(cfg.0);
@@ -277,6 +401,19 @@ impl Command {
     }
 
     /// Configuration for the child process's stdout handle (file descriptor 1).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::{Command, Stdio};
+    ///
+    /// Command::new("ls")
+    ///         .stdout(Stdio::null())
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn stdout(&mut self, cfg: Stdio) -> &mut Command {
         self.inner.stdout(cfg.0);
@@ -284,6 +421,19 @@ impl Command {
     }
 
     /// Configuration for the child process's stderr handle (file descriptor 2).
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::{Command, Stdio};
+    ///
+    /// Command::new("ls")
+    ///         .stderr(Stdio::null())
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn stderr(&mut self, cfg: Stdio) -> &mut Command {
         self.inner.stderr(cfg.0);
@@ -293,6 +443,18 @@ impl Command {
     /// Executes the command as a child process, returning a handle to it.
     ///
     /// By default, stdin, stdout and stderr are inherited from the parent.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// Command::new("ls")
+    ///         .spawn()
+    ///         .expect("ls command failed to start");
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn spawn(&mut self) -> io::Result<Child> {
         self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
@@ -308,8 +470,10 @@ impl Command {
     ///
     /// ```should_panic
     /// use std::process::Command;
-    /// let output = Command::new("/bin/cat").arg("file.txt").output()
-    ///     .expect("failed to execute process");
+    /// let output = Command::new("/bin/cat")
+    ///                      .arg("file.txt")
+    ///                      .output()
+    ///                      .expect("failed to execute process");
     ///
     /// println!("status: {}", output.status);
     /// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
@@ -333,8 +497,10 @@ impl Command {
     /// ```should_panic
     /// use std::process::Command;
     ///
-    /// let status = Command::new("/bin/cat").arg("file.txt").status()
-    ///     .expect("failed to execute process");
+    /// let status = Command::new("/bin/cat")
+    ///                      .arg("file.txt")
+    ///                      .status()
+    ///                      .expect("failed to execute process");
     ///
     /// println!("process exited with: {}", status);
     ///
@@ -439,6 +605,23 @@ pub struct ExitStatus(imp::ExitStatus);
 impl ExitStatus {
     /// Was termination successful? Signal termination not considered a success,
     /// and success is defined as a zero exit status.
+    ///
+    /// # Examples
+    ///
+    /// ```rust,no_run
+    /// use std::process::Command;
+    ///
+    /// let status = Command::new("mkdir")
+    ///                      .arg("projects")
+    ///                      .status()
+    ///                      .expect("failed to execute mkdir");
+    ///
+    /// if status.success() {
+    ///     println!("'projects/' directory created");
+    /// } else {
+    ///     println!("failed to create 'projects/' directory");
+    /// }
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn success(&self) -> bool {
         self.0.success()
@@ -459,6 +642,12 @@ impl AsInner<imp::ExitStatus> for ExitStatus {
     fn as_inner(&self) -> &imp::ExitStatus { &self.0 }
 }
 
+impl FromInner<imp::ExitStatus> for ExitStatus {
+    fn from_inner(s: imp::ExitStatus) -> ExitStatus {
+        ExitStatus(s)
+    }
+}
+
 #[stable(feature = "process", since = "1.0.0")]
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -469,12 +658,42 @@ impl fmt::Display for ExitStatus {
 impl Child {
     /// Forces the child to exit. This is equivalent to sending a
     /// SIGKILL on unix platforms.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// let mut command = Command::new("yes");
+    /// if let Ok(mut child) = command.spawn() {
+    ///     child.kill().expect("command wasn't running");
+    /// } else {
+    ///     println!("yes command didn't start");
+    /// }
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn kill(&mut self) -> io::Result<()> {
         self.handle.kill()
     }
 
     /// Returns the OS-assigned process identifier associated with this child.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// let mut command = Command::new("ls");
+    /// if let Ok(child) = command.spawn() {
+    ///     println!("Child's id is {}", child.id());
+    /// } else {
+    ///     println!("ls command didn't start");
+    /// }
+    /// ```
     #[stable(feature = "process_id", since = "1.3.0")]
     pub fn id(&self) -> u32 {
         self.handle.id()
@@ -488,6 +707,22 @@ impl Child {
     /// before waiting. This helps avoid deadlock: it ensures that the
     /// child does not block waiting for input from the parent, while
     /// the parent waits for the child to exit.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// let mut command = Command::new("ls");
+    /// if let Ok(mut child) = command.spawn() {
+    ///     child.wait().expect("command wasn't running");
+    ///     println!("Child has finished its execution!");
+    /// } else {
+    ///     println!("ls command didn't start");
+    /// }
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn wait(&mut self) -> io::Result<ExitStatus> {
         drop(self.stdin.take());
@@ -513,16 +748,17 @@ impl Child {
     /// ```should_panic
     /// use std::process::{Command, Stdio};
     ///
-    /// let mut child = Command::new("/bin/cat")
-    ///                         .arg("file.txt")
-    ///                         .stdout(Stdio::piped())
-    ///                         .spawn()
-    ///                         .expect("failed to execute child");
+    /// let child = Command::new("/bin/cat")
+    ///     .arg("file.txt")
+    ///     .stdout(Stdio::piped())
+    ///     .spawn()
+    ///     .expect("failed to execute child");
     ///
-    /// let ecode = child.wait_with_output()
-    ///                  .expect("failed to wait on child");
+    /// let output = child
+    ///     .wait_with_output()
+    ///     .expect("failed to wait on child");
     ///
-    /// assert!(ecode.status.success());
+    /// assert!(output.status.success());
     /// ```
     ///
     #[stable(feature = "process", since = "1.0.0")]
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index 83091c72c0d..5a7c0fe4816 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -25,12 +25,7 @@
 
 
 // Reexport some of our utilities which are expected by other crates.
-pub use sys_common::unwind::{begin_unwind, begin_unwind_fmt};
-
-// Rust runtime's startup objects depend on these symbols, so they must be public.
-// Since sys_common isn't public, we have to re-export them here.
-#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
-pub use sys_common::unwind::imp::eh_frame_registry::*;
+pub use panicking::{begin_panic, begin_panic_fmt};
 
 #[cfg(not(test))]
 #[lang = "start"]
@@ -53,7 +48,7 @@ fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
         // created. Note that this isn't necessary in general for new threads,
         // but we just do this to name the main thread and to give it correct
         // info about the stack bounds.
-        let thread: Thread = NewThread::new(Some("<main>".to_owned()));
+        let thread: Thread = NewThread::new(Some("main".to_owned()));
         thread_info::set(main_guard, thread);
 
         // Store our args if necessary in a squirreled away location
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
index b543240c15a..b1267acdee6 100644
--- a/src/libstd/sync/barrier.rs
+++ b/src/libstd/sync/barrier.rs
@@ -71,7 +71,7 @@ impl Barrier {
         }
     }
 
-    /// Blocks the current thread until all threads has rendezvoused here.
+    /// Blocks the current thread until all threads have rendezvoused here.
     ///
     /// Barriers are re-usable after all threads have rendezvoused once, and can
     /// be used continuously.
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 57932f03796..3c52ebc72f2 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -15,7 +15,7 @@ use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
 use sys_common::mutex as sys_mutex;
 use sys_common::poison::{self, LockResult};
-use time::{Instant, Duration};
+use time::Duration;
 
 /// A type indicating whether a timed wait on a condition variable returned
 /// due to a time out or not.
@@ -72,46 +72,19 @@ impl WaitTimeoutResult {
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-pub struct Condvar { inner: Box<StaticCondvar> }
-
-/// Statically allocated condition variables.
-///
-/// This structure is identical to `Condvar` except that it is suitable for use
-/// in static initializers for other structures.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_condvar)]
-///
-/// use std::sync::{StaticCondvar, CONDVAR_INIT};
-///
-/// static CVAR: StaticCondvar = CONDVAR_INIT;
-/// ```
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-pub struct StaticCondvar {
-    inner: sys::Condvar,
+pub struct Condvar {
+    inner: Box<sys::Condvar>,
     mutex: AtomicUsize,
 }
 
-/// Constant initializer for a statically allocated condition variable.
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-pub const CONDVAR_INIT: StaticCondvar = StaticCondvar::new();
-
 impl Condvar {
     /// Creates a new condition variable which is ready to be waited on and
     /// notified.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> Condvar {
         Condvar {
-            inner: box StaticCondvar {
-                inner: sys::Condvar::new(),
-                mutex: AtomicUsize::new(0),
-            }
+            inner: box sys::Condvar::new(),
+            mutex: AtomicUsize::new(0),
         }
     }
 
@@ -144,9 +117,16 @@ impl Condvar {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
-        unsafe {
-            let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait(guard)
+        let poisoned = unsafe {
+            let lock = mutex::guard_lock(&guard);
+            self.verify(lock);
+            self.inner.wait(lock);
+            mutex::guard_poison(&guard).get()
+        };
+        if poisoned {
+            Err(PoisonError::new(guard))
+        } else {
+            Ok(guard)
         }
     }
 
@@ -193,9 +173,16 @@ impl Condvar {
     pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>,
                                dur: Duration)
                                -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
-        unsafe {
-            let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait_timeout(guard, dur)
+        let (poisoned, result) = unsafe {
+            let lock = mutex::guard_lock(&guard);
+            self.verify(lock);
+            let success = self.inner.wait_timeout(lock, dur);
+            (mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
+        };
+        if poisoned {
+            Err(PoisonError::new((guard, result)))
+        } else {
+            Ok((guard, result))
         }
     }
 
@@ -207,7 +194,9 @@ impl Condvar {
     ///
     /// To wake up all threads, see `notify_all()`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
+    pub fn notify_one(&self) {
+        unsafe { self.inner.notify_one() }
+    }
 
     /// Wakes up all blocked threads on this condvar.
     ///
@@ -217,159 +206,8 @@ impl Condvar {
     ///
     /// To wake up only one thread, see `notify_one()`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
-}
-
-#[stable(feature = "condvar_default", since = "1.9.0")]
-impl Default for Condvar {
-    fn default() -> Condvar {
-        Condvar::new()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Drop for Condvar {
-    fn drop(&mut self) {
-        unsafe { self.inner.inner.destroy() }
-    }
-}
-
-impl StaticCondvar {
-    /// Creates a new condition variable
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub const fn new() -> StaticCondvar {
-        StaticCondvar {
-            inner: sys::Condvar::new(),
-            mutex: AtomicUsize::new(0),
-        }
-    }
-
-    /// Blocks the current thread until this condition variable receives a
-    /// notification.
-    ///
-    /// See `Condvar::wait`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>)
-                       -> LockResult<MutexGuard<'a, T>> {
-        let poisoned = unsafe {
-            let lock = mutex::guard_lock(&guard);
-            self.verify(lock);
-            self.inner.wait(lock);
-            mutex::guard_poison(&guard).get()
-        };
-        if poisoned {
-            Err(PoisonError::new(guard))
-        } else {
-            Ok(guard)
-        }
-    }
-
-    /// Waits on this condition variable for a notification, timing out after a
-    /// specified duration.
-    ///
-    /// See `Condvar::wait_timeout`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait_timeout<'a, T>(&'static self,
-                               guard: MutexGuard<'a, T>,
-                               timeout: Duration)
-                               -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
-        let (poisoned, result) = unsafe {
-            let lock = mutex::guard_lock(&guard);
-            self.verify(lock);
-            let success = self.inner.wait_timeout(lock, timeout);
-            (mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
-        };
-        if poisoned {
-            Err(PoisonError::new((guard, result)))
-        } else {
-            Ok((guard, result))
-        }
-    }
-
-    /// Waits on this condition variable for a notification, timing out after a
-    /// specified duration.
-    ///
-    /// The implementation will repeatedly wait while the duration has not
-    /// passed and the function returns `false`.
-    ///
-    /// See `Condvar::wait_timeout_with`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait_timeout_with<'a, T, F>(&'static self,
-                                       guard: MutexGuard<'a, T>,
-                                       dur: Duration,
-                                       mut f: F)
-                                       -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
-            where F: FnMut(LockResult<&mut T>) -> bool {
-        // This could be made more efficient by pushing the implementation into
-        // sys::condvar
-        let start = Instant::now();
-        let mut guard_result: LockResult<MutexGuard<'a, T>> = Ok(guard);
-        while !f(guard_result
-                    .as_mut()
-                    .map(|g| &mut **g)
-                    .map_err(|e| PoisonError::new(&mut **e.get_mut()))) {
-            let consumed = start.elapsed();
-            let guard = guard_result.unwrap_or_else(|e| e.into_inner());
-            let (new_guard_result, timed_out) = if consumed > dur {
-                (Ok(guard), WaitTimeoutResult(true))
-            } else {
-                match self.wait_timeout(guard, dur - consumed) {
-                    Ok((new_guard, timed_out)) => (Ok(new_guard), timed_out),
-                    Err(err) => {
-                        let (new_guard, no_timeout) = err.into_inner();
-                        (Err(PoisonError::new(new_guard)), no_timeout)
-                    }
-                }
-            };
-            guard_result = new_guard_result;
-            if timed_out.timed_out() {
-                let result = f(guard_result
-                                    .as_mut()
-                                    .map(|g| &mut **g)
-                                    .map_err(|e| PoisonError::new(&mut **e.get_mut())));
-                let result = WaitTimeoutResult(!result);
-                return poison::map_result(guard_result, |g| (g, result));
-            }
-        }
-
-        poison::map_result(guard_result, |g| (g, WaitTimeoutResult(false)))
-    }
-
-    /// Wakes up one blocked thread on this condvar.
-    ///
-    /// See `Condvar::notify_one`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
-
-    /// Wakes up all blocked threads on this condvar.
-    ///
-    /// See `Condvar::notify_all`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
-
-    /// Deallocates all resources associated with this static condvar.
-    ///
-    /// This method is unsafe to call as there is no guarantee that there are no
-    /// active users of the condvar, and this also doesn't prevent any future
-    /// users of the condvar. This method is required to be called to not leak
-    /// memory on all platforms.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub unsafe fn destroy(&'static self) {
-        self.inner.destroy()
+    pub fn notify_all(&self) {
+        unsafe { self.inner.notify_all() }
     }
 
     fn verify(&self, mutex: &sys_mutex::Mutex) {
@@ -391,14 +229,26 @@ impl StaticCondvar {
     }
 }
 
+#[stable(feature = "condvar_default", since = "1.9.0")]
+impl Default for Condvar {
+    fn default() -> Condvar {
+        Condvar::new()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Drop for Condvar {
+    fn drop(&mut self) {
+        unsafe { self.inner.destroy() }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use prelude::v1::*;
 
-    use super::StaticCondvar;
     use sync::mpsc::channel;
-    use sync::{StaticMutex, Condvar, Mutex, Arc};
-    use sync::atomic::{AtomicUsize, Ordering};
+    use sync::{Condvar, Mutex, Arc};
     use thread;
     use time::Duration;
     use u32;
@@ -411,26 +261,19 @@ mod tests {
     }
 
     #[test]
-    fn static_smoke() {
-        static C: StaticCondvar = StaticCondvar::new();
-        C.notify_one();
-        C.notify_all();
-        unsafe { C.destroy(); }
-    }
-
-    #[test]
     fn notify_one() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let g = M.lock().unwrap();
+        let g = m.lock().unwrap();
         let _t = thread::spawn(move|| {
-            let _g = M.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        let g = C.wait(g).unwrap();
+        let g = c.wait(g).unwrap();
         drop(g);
-        unsafe { C.destroy(); M.destroy(); }
     }
 
     #[test]
@@ -471,84 +314,41 @@ mod tests {
 
     #[test]
     fn wait_timeout_ms() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout(g, Duration::from_millis(1)).unwrap();
+        let g = m.lock().unwrap();
+        let (g, _no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
         // spurious wakeups mean this isn't necessarily true
         // assert!(!no_timeout);
         let _t = thread::spawn(move || {
-            let _g = M.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        let (g, timeout_res) = C.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
+        let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
         assert!(!timeout_res.timed_out());
         drop(g);
-        unsafe { C.destroy(); M.destroy(); }
-    }
-
-    #[test]
-    fn wait_timeout_with() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
-        static S: AtomicUsize = AtomicUsize::new(0);
-
-        let g = M.lock().unwrap();
-        let (g, timed_out) = C.wait_timeout_with(g, Duration::new(0, 1000), |_| {
-            false
-        }).unwrap();
-        assert!(timed_out.timed_out());
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-            let g = M.lock().unwrap();
-            S.store(1, Ordering::SeqCst);
-            C.notify_one();
-            drop(g);
-
-            rx.recv().unwrap();
-            let g = M.lock().unwrap();
-            S.store(2, Ordering::SeqCst);
-            C.notify_one();
-            drop(g);
-
-            rx.recv().unwrap();
-            let _g = M.lock().unwrap();
-            S.store(3, Ordering::SeqCst);
-            C.notify_one();
-        });
-
-        let mut state = 0;
-        let day = 24 * 60 * 60;
-        let (_g, timed_out) = C.wait_timeout_with(g, Duration::new(day, 0), |_| {
-            assert_eq!(state, S.load(Ordering::SeqCst));
-            tx.send(()).unwrap();
-            state += 1;
-            match state {
-                1|2 => false,
-                _ => true,
-            }
-        }).unwrap();
-        assert!(!timed_out.timed_out());
     }
 
     #[test]
     #[should_panic]
     fn two_mutexes() {
-        static M1: StaticMutex = StaticMutex::new();
-        static M2: StaticMutex = StaticMutex::new();
-        static C: StaticCondvar = StaticCondvar::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let mut g = M1.lock().unwrap();
+        let mut g = m.lock().unwrap();
         let _t = thread::spawn(move|| {
-            let _g = M1.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        g = C.wait(g).unwrap();
+        g = c.wait(g).unwrap();
         drop(g);
 
-        let _ = C.wait(M2.lock().unwrap()).unwrap();
+        let m = Mutex::new(());
+        let _ = c.wait(m.lock().unwrap()).unwrap();
     }
 }
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index c20b422d40c..289b47b3484 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -25,19 +25,15 @@ pub use core::sync::atomic;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::barrier::{Barrier, BarrierWaitResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
+pub use self::condvar::{Condvar, WaitTimeoutResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::mutex::MUTEX_INIT;
+pub use self::mutex::{Mutex, MutexGuard};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::once::{Once, ONCE_INIT};
+pub use self::once::{Once, OnceState, ONCE_INIT};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
+pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
 
 pub mod mpsc;
 
diff --git a/src/libstd/sync/mpsc/blocking.rs b/src/libstd/sync/mpsc/blocking.rs
index 0e5a9859116..4a70de0e7d8 100644
--- a/src/libstd/sync/mpsc/blocking.rs
+++ b/src/libstd/sync/mpsc/blocking.rs
@@ -16,6 +16,7 @@ use sync::Arc;
 use marker::{Sync, Send};
 use mem;
 use clone::Clone;
+use time::Instant;
 
 struct Inner {
     thread: Thread,
@@ -74,7 +75,6 @@ impl SignalToken {
     pub unsafe fn cast_from_usize(signal_ptr: usize) -> SignalToken {
         SignalToken { inner: mem::transmute(signal_ptr) }
     }
-
 }
 
 impl WaitToken {
@@ -83,4 +83,16 @@ impl WaitToken {
             thread::park()
         }
     }
+
+    /// Returns true if we wake up normally, false otherwise.
+    pub fn wait_max_until(self, end: Instant) -> bool {
+        while !self.inner.woken.load(Ordering::SeqCst) {
+            let now = Instant::now();
+            if now >= end {
+                return false;
+            }
+            thread::park_timeout(end - now)
+        }
+        true
+    }
 }
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index dbcc2bc95bc..11f785dffd1 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -134,9 +134,9 @@
 // senders. Under the hood, however, there are actually three flavors of
 // channels in play.
 //
-// * Flavor::Oneshots - these channels are highly optimized for the one-send use case.
-//              They contain as few atomics as possible and involve one and
-//              exactly one allocation.
+// * Flavor::Oneshots - these channels are highly optimized for the one-send use
+//                      case. They contain as few atomics as possible and
+//                      involve one and exactly one allocation.
 // * Streams - these channels are optimized for the non-shared use case. They
 //             use a different concurrent queue that is more tailored for this
 //             use case. The initial allocation of this flavor of channel is not
@@ -148,9 +148,9 @@
 //
 // ## Concurrent queues
 //
-// The basic idea of Rust's Sender/Receiver types is that send() never blocks, but
-// recv() obviously blocks. This means that under the hood there must be some
-// shared and concurrent queue holding all of the actual data.
+// The basic idea of Rust's Sender/Receiver types is that send() never blocks,
+// but recv() obviously blocks. This means that under the hood there must be
+// some shared and concurrent queue holding all of the actual data.
 //
 // With two flavors of channels, two flavors of queues are also used. We have
 // chosen to use queues from a well-known author that are abbreviated as SPSC
@@ -271,6 +271,7 @@ use fmt;
 use mem;
 use cell::UnsafeCell;
 use marker::Reflect;
+use time::{Duration, Instant};
 
 #[unstable(feature = "mpsc_select", issue = "27800")]
 pub use self::select::{Select, Handle};
@@ -310,6 +311,17 @@ pub struct Iter<'a, T: 'a> {
     rx: &'a Receiver<T>
 }
 
+/// An iterator that attempts to yield all pending values for a receiver.
+/// `None` will be returned when there are no pending values remaining or
+/// if the corresponding channel has hung up.
+///
+/// This Iterator will never block the caller in order to wait for data to
+/// become available. Instead, it will return `None`.
+#[unstable(feature = "receiver_try_iter", issue = "34931")]
+pub struct TryIter<'a, T: 'a> {
+    rx: &'a Receiver<T>
+}
+
 /// An owning iterator over messages on a receiver, this iterator will block
 /// whenever `next` is called, waiting for a new message, and `None` will be
 /// returned when the corresponding channel has hung up.
@@ -379,6 +391,19 @@ pub enum TryRecvError {
     Disconnected,
 }
 
+/// This enumeration is the list of possible errors that `recv_timeout` could
+/// not return data when called.
+#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+#[unstable(feature = "mpsc_recv_timeout", issue = "34029")]
+pub enum RecvTimeoutError {
+    /// This channel is currently empty, but the sender(s) have not yet
+    /// disconnected, so data may yet become available.
+    Timeout,
+    /// This channel's sending half has become disconnected, and there will
+    /// never be any more data received on this channel
+    Disconnected,
+}
+
 /// This enumeration is the list of the possible error outcomes for the
 /// `SyncSender::try_send` method.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -535,7 +560,7 @@ impl<T> Sender<T> {
     ///
     /// // This send will fail because the receiver is gone
     /// drop(rx);
-    /// assert_eq!(tx.send(1).err().unwrap().0, 1);
+    /// assert_eq!(tx.send(1).unwrap_err().0, 1);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
@@ -838,30 +863,30 @@ impl<T> Receiver<T> {
         loop {
             let new_port = match *unsafe { self.inner() } {
                 Flavor::Oneshot(ref p) => {
-                    match unsafe { (*p.get()).recv() } {
+                    match unsafe { (*p.get()).recv(None) } {
                         Ok(t) => return Ok(t),
-                        Err(oneshot::Empty) => return unreachable!(),
                         Err(oneshot::Disconnected) => return Err(RecvError),
                         Err(oneshot::Upgraded(rx)) => rx,
+                        Err(oneshot::Empty) => unreachable!(),
                     }
                 }
                 Flavor::Stream(ref p) => {
-                    match unsafe { (*p.get()).recv() } {
+                    match unsafe { (*p.get()).recv(None) } {
                         Ok(t) => return Ok(t),
-                        Err(stream::Empty) => return unreachable!(),
                         Err(stream::Disconnected) => return Err(RecvError),
                         Err(stream::Upgraded(rx)) => rx,
+                        Err(stream::Empty) => unreachable!(),
                     }
                 }
                 Flavor::Shared(ref p) => {
-                    match unsafe { (*p.get()).recv() } {
+                    match unsafe { (*p.get()).recv(None) } {
                         Ok(t) => return Ok(t),
-                        Err(shared::Empty) => return unreachable!(),
                         Err(shared::Disconnected) => return Err(RecvError),
+                        Err(shared::Empty) => unreachable!(),
                     }
                 }
                 Flavor::Sync(ref p) => return unsafe {
-                    (*p.get()).recv().map_err(|()| RecvError)
+                    (*p.get()).recv(None).map_err(|_| RecvError)
                 }
             };
             unsafe {
@@ -870,12 +895,114 @@ impl<T> Receiver<T> {
         }
     }
 
+    /// Attempts to wait for a value on this receiver, returning an error if the
+    /// corresponding channel has hung up, or if it waits more than `timeout`.
+    ///
+    /// This function will always block the current thread if there is no data
+    /// available and it's possible for more data to be sent. Once a message is
+    /// sent to the corresponding `Sender`, then this receiver will wake up and
+    /// return that message.
+    ///
+    /// If the corresponding `Sender` has disconnected, or it disconnects while
+    /// this call is blocking, this call will wake up and return `Err` to
+    /// indicate that no more messages can ever be received on this channel.
+    /// However, since channels are buffered, messages sent before the disconnect
+    /// will still be properly received.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(mpsc_recv_timeout)]
+    ///
+    /// use std::sync::mpsc::{self, RecvTimeoutError};
+    /// use std::time::Duration;
+    ///
+    /// let (send, recv) = mpsc::channel::<()>();
+    ///
+    /// let timeout = Duration::from_millis(100);
+    /// assert_eq!(Err(RecvTimeoutError::Timeout), recv.recv_timeout(timeout));
+    /// ```
+    #[unstable(feature = "mpsc_recv_timeout", issue = "34029")]
+    pub fn recv_timeout(&self, timeout: Duration) -> Result<T, RecvTimeoutError> {
+        // Do an optimistic try_recv to avoid the performance impact of
+        // Instant::now() in the full-channel case.
+        match self.try_recv() {
+            Ok(result)
+                => Ok(result),
+            Err(TryRecvError::Disconnected)
+                => Err(RecvTimeoutError::Disconnected),
+            Err(TryRecvError::Empty)
+                => self.recv_max_until(Instant::now() + timeout)
+        }
+    }
+
+    fn recv_max_until(&self, deadline: Instant) -> Result<T, RecvTimeoutError> {
+        use self::RecvTimeoutError::*;
+
+        loop {
+            let port_or_empty = match *unsafe { self.inner() } {
+                Flavor::Oneshot(ref p) => {
+                    match unsafe { (*p.get()).recv(Some(deadline)) } {
+                        Ok(t) => return Ok(t),
+                        Err(oneshot::Disconnected) => return Err(Disconnected),
+                        Err(oneshot::Upgraded(rx)) => Some(rx),
+                        Err(oneshot::Empty) => None,
+                    }
+                }
+                Flavor::Stream(ref p) => {
+                    match unsafe { (*p.get()).recv(Some(deadline)) } {
+                        Ok(t) => return Ok(t),
+                        Err(stream::Disconnected) => return Err(Disconnected),
+                        Err(stream::Upgraded(rx)) => Some(rx),
+                        Err(stream::Empty) => None,
+                    }
+                }
+                Flavor::Shared(ref p) => {
+                    match unsafe { (*p.get()).recv(Some(deadline)) } {
+                        Ok(t) => return Ok(t),
+                        Err(shared::Disconnected) => return Err(Disconnected),
+                        Err(shared::Empty) => None,
+                    }
+                }
+                Flavor::Sync(ref p) => {
+                    match unsafe { (*p.get()).recv(Some(deadline)) } {
+                        Ok(t) => return Ok(t),
+                        Err(sync::Disconnected) => return Err(Disconnected),
+                        Err(sync::Empty) => None,
+                    }
+                }
+            };
+
+            if let Some(new_port) = port_or_empty {
+                unsafe {
+                    mem::swap(self.inner_mut(), new_port.inner_mut());
+                }
+            }
+
+            // If we're already passed the deadline, and we're here without
+            // data, return a timeout, else try again.
+            if Instant::now() >= deadline {
+                return Err(Timeout);
+            }
+        }
+    }
+
     /// Returns an iterator that will block waiting for messages, but never
     /// `panic!`. It will return `None` when the channel has hung up.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
         Iter { rx: self }
     }
+
+    /// Returns an iterator that will attempt to yield all pending values.
+    /// It will return `None` if there are no more pending values or if the
+    /// channel has hung up. The iterator will never `panic!` or block the
+    /// user by waiting for values.
+    #[unstable(feature = "receiver_try_iter", issue = "34931")]
+    pub fn try_iter(&self) -> TryIter<T> {
+        TryIter { rx: self }
+    }
+
 }
 
 impl<T> select::Packet for Receiver<T> {
@@ -971,6 +1098,13 @@ impl<'a, T> Iterator for Iter<'a, T> {
     fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
 }
 
+#[unstable(feature = "receiver_try_iter", issue = "34931")]
+impl<'a, T> Iterator for TryIter<'a, T> {
+    type Item = T;
+
+    fn next(&mut self) -> Option<T> { self.rx.try_recv().ok() }
+}
+
 #[stable(feature = "receiver_into_iter", since = "1.1.0")]
 impl<'a, T> IntoIterator for &'a Receiver<T> {
     type Item = T;
@@ -1141,6 +1275,7 @@ mod tests {
     use env;
     use super::*;
     use thread;
+    use time::{Duration, Instant};
 
     pub fn stress_factor() -> usize {
         match env::var("RUST_TEST_STRESS") {
@@ -1540,6 +1675,87 @@ mod tests {
     }
 
     #[test]
+    fn oneshot_single_thread_recv_timeout() {
+        let (tx, rx) = channel();
+        tx.send(()).unwrap();
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
+        tx.send(()).unwrap();
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
+    }
+
+    #[test]
+    fn stress_recv_timeout_two_threads() {
+        let (tx, rx) = channel();
+        let stress = stress_factor() + 100;
+        let timeout = Duration::from_millis(100);
+
+        thread::spawn(move || {
+            for i in 0..stress {
+                if i % 2 == 0 {
+                    thread::sleep(timeout * 2);
+                }
+                tx.send(1usize).unwrap();
+            }
+        });
+
+        let mut recv_count = 0;
+        loop {
+            match rx.recv_timeout(timeout) {
+                Ok(n) => {
+                    assert_eq!(n, 1usize);
+                    recv_count += 1;
+                }
+                Err(RecvTimeoutError::Timeout) => continue,
+                Err(RecvTimeoutError::Disconnected) => break,
+            }
+        }
+
+        assert_eq!(recv_count, stress);
+    }
+
+    #[test]
+    fn recv_timeout_upgrade() {
+        let (tx, rx) = channel::<()>();
+        let timeout = Duration::from_millis(1);
+        let _tx_clone = tx.clone();
+
+        let start = Instant::now();
+        assert_eq!(rx.recv_timeout(timeout), Err(RecvTimeoutError::Timeout));
+        assert!(Instant::now() >= start + timeout);
+    }
+
+    #[test]
+    fn stress_recv_timeout_shared() {
+        let (tx, rx) = channel();
+        let stress = stress_factor() + 100;
+
+        for i in 0..stress {
+            let tx = tx.clone();
+            thread::spawn(move || {
+                thread::sleep(Duration::from_millis(i as u64 * 10));
+                tx.send(1usize).unwrap();
+            });
+        }
+
+        drop(tx);
+
+        let mut recv_count = 0;
+        loop {
+            match rx.recv_timeout(Duration::from_millis(10)) {
+                Ok(n) => {
+                    assert_eq!(n, 1usize);
+                    recv_count += 1;
+                }
+                Err(RecvTimeoutError::Timeout) => continue,
+                Err(RecvTimeoutError::Disconnected) => break,
+            }
+        }
+
+        assert_eq!(recv_count, stress);
+    }
+
+    #[test]
     fn recv_a_lot() {
         // Regression test that we don't run out of stack in scheduler context
         let (tx, rx) = channel();
@@ -1548,6 +1764,24 @@ mod tests {
     }
 
     #[test]
+    fn shared_recv_timeout() {
+        let (tx, rx) = channel();
+        let total = 5;
+        for _ in 0..total {
+            let tx = tx.clone();
+            thread::spawn(move|| {
+                tx.send(()).unwrap();
+            });
+        }
+
+        for _ in 0..total { rx.recv().unwrap(); }
+
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
+        tx.send(()).unwrap();
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(()));
+    }
+
+    #[test]
     fn shared_chan_stress() {
         let (tx, rx) = channel();
         let total = stress_factor() + 100;
@@ -1609,6 +1843,34 @@ mod tests {
     }
 
     #[test]
+    fn test_recv_try_iter() {
+        let (request_tx, request_rx) = channel();
+        let (response_tx, response_rx) = channel();
+
+        // Request `x`s until we have `6`.
+        let t = thread::spawn(move|| {
+            let mut count = 0;
+            loop {
+                for x in response_rx.try_iter() {
+                    count += x;
+                    if count == 6 {
+                        return count;
+                    }
+                }
+                request_tx.send(()).unwrap();
+            }
+        });
+
+        for _ in request_rx.iter() {
+            if response_tx.send(2).is_err() {
+                break;
+            }
+        }
+
+        assert_eq!(t.join().unwrap(), 6);
+    }
+
+    #[test]
     fn test_recv_into_iter_owned() {
         let mut iter = {
           let (tx, rx) = channel::<i32>();
@@ -1689,6 +1951,7 @@ mod sync_tests {
     use env;
     use thread;
     use super::*;
+    use time::Duration;
 
     pub fn stress_factor() -> usize {
         match env::var("RUST_TEST_STRESS") {
@@ -1721,6 +1984,14 @@ mod sync_tests {
     }
 
     #[test]
+    fn recv_timeout() {
+        let (tx, rx) = sync_channel::<i32>(1);
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Err(RecvTimeoutError::Timeout));
+        tx.send(1).unwrap();
+        assert_eq!(rx.recv_timeout(Duration::from_millis(1)), Ok(1));
+    }
+
+    #[test]
     fn smoke_threads() {
         let (tx, rx) = sync_channel::<i32>(0);
         let _t = thread::spawn(move|| {
@@ -1802,6 +2073,67 @@ mod sync_tests {
     }
 
     #[test]
+    fn stress_recv_timeout_two_threads() {
+        let (tx, rx) = sync_channel::<i32>(0);
+
+        thread::spawn(move|| {
+            for _ in 0..10000 { tx.send(1).unwrap(); }
+        });
+
+        let mut recv_count = 0;
+        loop {
+            match rx.recv_timeout(Duration::from_millis(1)) {
+                Ok(v) => {
+                    assert_eq!(v, 1);
+                    recv_count += 1;
+                },
+                Err(RecvTimeoutError::Timeout) => continue,
+                Err(RecvTimeoutError::Disconnected) => break,
+            }
+        }
+
+        assert_eq!(recv_count, 10000);
+    }
+
+    #[test]
+    fn stress_recv_timeout_shared() {
+        const AMT: u32 = 1000;
+        const NTHREADS: u32 = 8;
+        let (tx, rx) = sync_channel::<i32>(0);
+        let (dtx, drx) = sync_channel::<()>(0);
+
+        thread::spawn(move|| {
+            let mut recv_count = 0;
+            loop {
+                match rx.recv_timeout(Duration::from_millis(10)) {
+                    Ok(v) => {
+                        assert_eq!(v, 1);
+                        recv_count += 1;
+                    },
+                    Err(RecvTimeoutError::Timeout) => continue,
+                    Err(RecvTimeoutError::Disconnected) => break,
+                }
+            }
+
+            assert_eq!(recv_count, AMT * NTHREADS);
+            assert!(rx.try_recv().is_err());
+
+            dtx.send(()).unwrap();
+        });
+
+        for _ in 0..NTHREADS {
+            let tx = tx.clone();
+            thread::spawn(move|| {
+                for _ in 0..AMT { tx.send(1).unwrap(); }
+            });
+        }
+
+        drop(tx);
+
+        drx.recv().unwrap();
+    }
+
+    #[test]
     fn stress_shared() {
         const AMT: u32 = 1000;
         const NTHREADS: u32 = 8;
@@ -1905,6 +2237,15 @@ mod sync_tests {
     }
 
     #[test]
+    fn oneshot_single_thread_try_recv_closed_with_data() {
+        let (tx, rx) = sync_channel::<i32>(1);
+        tx.send(10).unwrap();
+        drop(tx);
+        assert_eq!(rx.try_recv(), Ok(10));
+        assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
+    }
+
+    #[test]
     fn oneshot_single_thread_peek_data() {
         let (tx, rx) = sync_channel::<i32>(1);
         assert_eq!(rx.try_recv(), Err(TryRecvError::Empty));
diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs
index cb930280964..7a35ea6bbaa 100644
--- a/src/libstd/sync/mpsc/oneshot.rs
+++ b/src/libstd/sync/mpsc/oneshot.rs
@@ -41,6 +41,7 @@ use sync::mpsc::Receiver;
 use sync::mpsc::blocking::{self, SignalToken};
 use core::mem;
 use sync::atomic::{AtomicUsize, Ordering};
+use time::Instant;
 
 // Various states you can find a port in.
 const EMPTY: usize = 0;          // initial state: no data, no blocked receiver
@@ -136,7 +137,7 @@ impl<T> Packet<T> {
         }
     }
 
-    pub fn recv(&mut self) -> Result<T, Failure<T>> {
+    pub fn recv(&mut self, deadline: Option<Instant>) -> Result<T, Failure<T>> {
         // Attempt to not block the thread (it's a little expensive). If it looks
         // like we're not empty, then immediately go through to `try_recv`.
         if self.state.load(Ordering::SeqCst) == EMPTY {
@@ -145,8 +146,16 @@ impl<T> Packet<T> {
 
             // race with senders to enter the blocking state
             if self.state.compare_and_swap(EMPTY, ptr, Ordering::SeqCst) == EMPTY {
-                wait_token.wait();
-                debug_assert!(self.state.load(Ordering::SeqCst) != EMPTY);
+                if let Some(deadline) = deadline {
+                    let timed_out = !wait_token.wait_max_until(deadline);
+                    // Try to reset the state
+                    if timed_out {
+                        try!(self.abort_selection().map_err(Upgraded));
+                    }
+                } else {
+                    wait_token.wait();
+                    debug_assert!(self.state.load(Ordering::SeqCst) != EMPTY);
+                }
             } else {
                 // drop the signal token, since we never blocked
                 drop(unsafe { SignalToken::cast_from_usize(ptr) });
diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs
index a3779931c7b..baa4db7e5c0 100644
--- a/src/libstd/sync/mpsc/shared.rs
+++ b/src/libstd/sync/mpsc/shared.rs
@@ -30,6 +30,7 @@ use sync::mpsc::select::StartResult::*;
 use sync::mpsc::select::StartResult;
 use sync::{Mutex, MutexGuard};
 use thread;
+use time::Instant;
 
 const DISCONNECTED: isize = isize::MIN;
 const FUDGE: isize = 1024;
@@ -66,7 +67,7 @@ impl<T> Packet<T> {
     // Creation of a packet *must* be followed by a call to postinit_lock
     // and later by inherit_blocker
     pub fn new() -> Packet<T> {
-        let p = Packet {
+        Packet {
             queue: mpsc::Queue::new(),
             cnt: AtomicIsize::new(0),
             steals: 0,
@@ -75,8 +76,7 @@ impl<T> Packet<T> {
             port_dropped: AtomicBool::new(false),
             sender_drain: AtomicIsize::new(0),
             select_lock: Mutex::new(()),
-        };
-        return p;
+        }
     }
 
     // This function should be used after newly created Packet
@@ -216,7 +216,7 @@ impl<T> Packet<T> {
         Ok(())
     }
 
-    pub fn recv(&mut self) -> Result<T, Failure> {
+    pub fn recv(&mut self, deadline: Option<Instant>) -> Result<T, Failure> {
         // This code is essentially the exact same as that found in the stream
         // case (see stream.rs)
         match self.try_recv() {
@@ -226,7 +226,14 @@ impl<T> Packet<T> {
 
         let (wait_token, signal_token) = blocking::tokens();
         if self.decrement(signal_token) == Installed {
-            wait_token.wait()
+            if let Some(deadline) = deadline {
+                let timed_out = !wait_token.wait_max_until(deadline);
+                if timed_out {
+                    self.abort_selection(false);
+                }
+            } else {
+                wait_token.wait();
+            }
         }
 
         match self.try_recv() {
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index ffd33f8518f..02506e7c2f3 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -265,15 +265,18 @@ mod tests {
 
             // Ensure the borrowchecker works
             match queue.peek() {
-                Some(vec) => match &**vec {
-                    // Note that `pop` is not allowed here due to borrow
-                    [1] => {}
-                    _ => return
+                Some(vec) => {
+                    assert_eq!(&*vec, &[1]);
                 },
                 None => unreachable!()
             }
 
-            queue.pop();
+            match queue.pop() {
+                Some(vec) => {
+                    assert_eq!(&*vec, &[1]);
+                },
+                None => unreachable!()
+            }
         }
     }
 
diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs
index e8012ca470b..aa1254c8641 100644
--- a/src/libstd/sync/mpsc/stream.rs
+++ b/src/libstd/sync/mpsc/stream.rs
@@ -25,6 +25,7 @@ use self::Message::*;
 use core::cmp;
 use core::isize;
 use thread;
+use time::Instant;
 
 use sync::atomic::{AtomicIsize, AtomicUsize, Ordering, AtomicBool};
 use sync::mpsc::Receiver;
@@ -172,7 +173,7 @@ impl<T> Packet<T> {
         Err(unsafe { SignalToken::cast_from_usize(ptr) })
     }
 
-    pub fn recv(&mut self) -> Result<T, Failure<T>> {
+    pub fn recv(&mut self, deadline: Option<Instant>) -> Result<T, Failure<T>> {
         // Optimistic preflight check (scheduling is expensive).
         match self.try_recv() {
             Err(Empty) => {}
@@ -183,7 +184,15 @@ impl<T> Packet<T> {
         // initiate the blocking protocol.
         let (wait_token, signal_token) = blocking::tokens();
         if self.decrement(signal_token).is_ok() {
-            wait_token.wait()
+            if let Some(deadline) = deadline {
+                let timed_out = !wait_token.wait_max_until(deadline);
+                if timed_out {
+                    try!(self.abort_selection(/* was_upgrade = */ false)
+                             .map_err(Upgraded));
+                }
+            } else {
+                wait_token.wait();
+            }
         }
 
         match self.try_recv() {
@@ -332,7 +341,7 @@ impl<T> Packet<T> {
         // the internal state.
         match self.queue.peek() {
             Some(&mut GoUp(..)) => {
-                match self.recv() {
+                match self.recv(None) {
                     Err(Upgraded(port)) => Err(port),
                     _ => unreachable!(),
                 }
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index b98fc2859af..9d13a71ff95 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -44,6 +44,7 @@ use sync::atomic::{Ordering, AtomicUsize};
 use sync::mpsc::blocking::{self, WaitToken, SignalToken};
 use sync::mpsc::select::StartResult::{self, Installed, Abort};
 use sync::{Mutex, MutexGuard};
+use time::Instant;
 
 pub struct Packet<T> {
     /// Only field outside of the mutex. Just done for kicks, but mainly because
@@ -126,6 +127,38 @@ fn wait<'a, 'b, T>(lock: &'a Mutex<State<T>>,
     lock.lock().unwrap() // relock
 }
 
+/// Same as wait, but waiting at most until `deadline`.
+fn wait_timeout_receiver<'a, 'b, T>(lock: &'a Mutex<State<T>>,
+                                    deadline: Instant,
+                                    mut guard: MutexGuard<'b, State<T>>,
+                                    success: &mut bool)
+                                    -> MutexGuard<'a, State<T>>
+{
+    let (wait_token, signal_token) = blocking::tokens();
+    match mem::replace(&mut guard.blocker, BlockedReceiver(signal_token)) {
+        NoneBlocked => {}
+        _ => unreachable!(),
+    }
+    drop(guard);         // unlock
+    *success = wait_token.wait_max_until(deadline);   // block
+    let mut new_guard = lock.lock().unwrap(); // relock
+    if !*success {
+        abort_selection(&mut new_guard);
+    }
+    new_guard
+}
+
+fn abort_selection<'a, T>(guard: &mut MutexGuard<'a , State<T>>) -> bool {
+    match mem::replace(&mut guard.blocker, NoneBlocked) {
+        NoneBlocked => true,
+        BlockedSender(token) => {
+            guard.blocker = BlockedSender(token);
+            true
+        }
+        BlockedReceiver(token) => { drop(token); false }
+    }
+}
+
 /// Wakes up a thread, dropping the lock at the correct time
 fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) {
     // We need to be careful to wake up the waiting thread *outside* of the mutex
@@ -238,22 +271,37 @@ impl<T> Packet<T> {
     //
     // When reading this, remember that there can only ever be one receiver at
     // time.
-    pub fn recv(&self) -> Result<T, ()> {
+    pub fn recv(&self, deadline: Option<Instant>) -> Result<T, Failure> {
         let mut guard = self.lock.lock().unwrap();
 
-        // Wait for the buffer to have something in it. No need for a while loop
-        // because we're the only receiver.
-        let mut waited = false;
+        let mut woke_up_after_waiting = false;
+        // Wait for the buffer to have something in it. No need for a
+        // while loop because we're the only receiver.
         if !guard.disconnected && guard.buf.size() == 0 {
-            guard = wait(&self.lock, guard, BlockedReceiver);
-            waited = true;
+            if let Some(deadline) = deadline {
+                guard = wait_timeout_receiver(&self.lock,
+                                              deadline,
+                                              guard,
+                                              &mut woke_up_after_waiting);
+            } else {
+                guard = wait(&self.lock, guard, BlockedReceiver);
+                woke_up_after_waiting = true;
+            }
+        }
+
+        // NB: Channel could be disconnected while waiting, so the order of
+        // these conditionals is important.
+        if guard.disconnected && guard.buf.size() == 0 {
+            return Err(Disconnected);
         }
-        if guard.disconnected && guard.buf.size() == 0 { return Err(()) }
 
         // Pick up the data, wake up our neighbors, and carry on
-        assert!(guard.buf.size() > 0);
+        assert!(guard.buf.size() > 0 || (deadline.is_some() && !woke_up_after_waiting));
+
+        if guard.buf.size() == 0 { return Err(Empty); }
+
         let ret = guard.buf.dequeue();
-        self.wakeup_senders(waited, guard);
+        self.wakeup_senders(woke_up_after_waiting, guard);
         Ok(ret)
     }
 
@@ -261,7 +309,7 @@ impl<T> Packet<T> {
         let mut guard = self.lock.lock().unwrap();
 
         // Easy cases first
-        if guard.disconnected { return Err(Disconnected) }
+        if guard.disconnected && guard.buf.size() == 0 { return Err(Disconnected) }
         if guard.buf.size() == 0 { return Err(Empty) }
 
         // Be sure to wake up neighbors
@@ -392,14 +440,7 @@ impl<T> Packet<T> {
     // The return value indicates whether there's data on this port.
     pub fn abort_selection(&self) -> bool {
         let mut guard = self.lock.lock().unwrap();
-        match mem::replace(&mut guard.blocker, NoneBlocked) {
-            NoneBlocked => true,
-            BlockedSender(token) => {
-                guard.blocker = BlockedSender(token);
-                true
-            }
-            BlockedReceiver(token) => { drop(token); false }
-        }
+        abort_selection(&mut guard)
     }
 }
 
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 90cc79dad66..6bc458397f1 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -114,12 +114,13 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Mutex<T: ?Sized> {
-    // Note that this static mutex is in a *box*, not inlined into the struct
-    // itself. Once a native mutex has been used once, its address can never
-    // change (it can't be moved). This mutex type can be safely moved at any
-    // time, so to ensure that the native mutex is used correctly we box the
-    // inner lock to give it a constant address.
-    inner: Box<StaticMutex>,
+    // Note that this mutex is in a *box*, not inlined into the struct itself.
+    // Once a native mutex has been used once, its address can never change (it
+    // can't be moved). This mutex type can be safely moved at any time, so to
+    // ensure that the native mutex is used correctly we box the inner lock to
+    // give it a constant address.
+    inner: Box<sys::Mutex>,
+    poison: poison::Flag,
     data: UnsafeCell<T>,
 }
 
@@ -130,37 +131,6 @@ unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 
-/// The static mutex type is provided to allow for static allocation of mutexes.
-///
-/// Note that this is a separate type because using a Mutex correctly means that
-/// it needs to have a destructor run. In Rust, statics are not allowed to have
-/// destructors. As a result, a `StaticMutex` has one extra method when compared
-/// to a `Mutex`, a `destroy` method. This method is unsafe to call, and
-/// documentation can be found directly on the method.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_mutex)]
-///
-/// use std::sync::{StaticMutex, MUTEX_INIT};
-///
-/// static LOCK: StaticMutex = MUTEX_INIT;
-///
-/// {
-///     let _g = LOCK.lock().unwrap();
-///     // do some productive work
-/// }
-/// // lock is unlocked here.
-/// ```
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-pub struct StaticMutex {
-    lock: sys::Mutex,
-    poison: poison::Flag,
-}
-
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
 ///
@@ -171,29 +141,26 @@ pub struct StaticMutex {
 pub struct MutexGuard<'a, T: ?Sized + 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
     // disregard field privacy).
-    __lock: &'a StaticMutex,
-    __data: &'a mut T,
+    __lock: &'a Mutex<T>,
     __poison: poison::Guard,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
 
-/// Static initialization of a mutex. This constant can be used to initialize
-/// other mutex constants.
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
-
 impl<T> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
-        Mutex {
-            inner: box StaticMutex::new(),
+        let mut m = Mutex {
+            inner: box sys::Mutex::new(),
+            poison: poison::Flag::new(),
             data: UnsafeCell::new(t),
+        };
+        unsafe {
+            m.inner.init();
         }
+        m
     }
 }
 
@@ -221,8 +188,8 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
         unsafe {
-            self.inner.lock.lock();
-            MutexGuard::new(&*self.inner, &self.data)
+            self.inner.lock();
+            MutexGuard::new(self)
         }
     }
 
@@ -242,8 +209,8 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
         unsafe {
-            if self.inner.lock.try_lock() {
-                Ok(MutexGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_lock() {
+                Ok(MutexGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -258,7 +225,7 @@ impl<T: ?Sized> Mutex<T> {
     #[inline]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn is_poisoned(&self) -> bool {
-        self.inner.poison.get()
+        self.poison.get()
     }
 
     /// Consumes this mutex, returning the underlying data.
@@ -270,21 +237,22 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "mutex_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner StaticMutex.
+        // `self` so there's no need to lock the inner lock.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `Mutex` impl-s `Drop`, we can't move out of it, so
         // we'll have to destructure it manually instead.
         unsafe {
-            // Like `let Mutex { inner, data } = self`.
-            let (inner, data) = {
-                let Mutex { ref inner, ref data } = self;
-                (ptr::read(inner), ptr::read(data))
+            // Like `let Mutex { inner, poison, data } = self`.
+            let (inner, poison, data) = {
+                let Mutex { ref inner, ref poison, ref data } = self;
+                (ptr::read(inner), ptr::read(poison), ptr::read(data))
             };
             mem::forget(self);
-            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+            inner.destroy();  // Keep in sync with the `Drop` impl.
+            drop(inner);
 
-            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+            poison::map_result(poison.borrow(), |_| data.into_inner())
         }
     }
 
@@ -300,9 +268,9 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "mutex_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner StaticMutex.
+        // there's no need to lock the inner lock.
         let data = unsafe { &mut *self.data.get() };
-        poison::map_result(self.inner.poison.borrow(), |_| data )
+        poison::map_result(self.poison.borrow(), |_| data )
     }
 }
 
@@ -315,7 +283,7 @@ impl<T: ?Sized> Drop for Mutex<T> {
         // dropped, that's not our job)
         //
         // IMPORTANT: This code must be kept in sync with `Mutex::into_inner`.
-        unsafe { self.inner.lock.destroy() }
+        unsafe { self.inner.destroy() }
     }
 }
 
@@ -339,66 +307,11 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
     }
 }
 
-struct Dummy(UnsafeCell<()>);
-unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
-
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-impl StaticMutex {
-    /// Creates a new mutex in an unlocked state ready for use.
-    pub const fn new() -> StaticMutex {
-        StaticMutex {
-            lock: sys::Mutex::new(),
-            poison: poison::Flag::new(),
-        }
-    }
-
-    /// Acquires this lock, see `Mutex::lock`
-    #[inline]
-    pub fn lock(&'static self) -> LockResult<MutexGuard<()>> {
-        unsafe {
-            self.lock.lock();
-            MutexGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to grab this lock, see `Mutex::try_lock`
-    #[inline]
-    pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> {
-        unsafe {
-            if self.lock.try_lock() {
-                Ok(MutexGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Deallocates resources associated with this static mutex.
-    ///
-    /// This method is unsafe because it provides no guarantees that there are
-    /// no active users of this mutex, and safety is not guaranteed if there are
-    /// active users of this mutex.
-    ///
-    /// This method is required to ensure that there are no memory leaks on
-    /// *all* platforms. It may be the case that some platforms do not leak
-    /// memory if this method is not called, but this is not guaranteed to be
-    /// true on all platforms.
-    pub unsafe fn destroy(&'static self) {
-        self.lock.destroy()
-    }
-}
-
 impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
-
-    unsafe fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
-           -> LockResult<MutexGuard<'mutex, T>> {
+    unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
             MutexGuard {
                 __lock: lock,
-                __data: &mut *data.get(),
                 __poison: guard,
             }
         })
@@ -409,12 +322,16 @@ impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
 impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
-    fn deref(&self) -> &T {self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
-    fn deref_mut(&mut self) -> &mut T { self.__data }
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe { &mut *self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -423,13 +340,13 @@ impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
     fn drop(&mut self) {
         unsafe {
             self.__lock.poison.done(&self.__poison);
-            self.__lock.lock.unlock();
+            self.__lock.inner.unlock();
         }
     }
 }
 
 pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
-    &guard.__lock.lock
+    &guard.__lock.inner
 }
 
 pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
@@ -441,7 +358,7 @@ mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
-    use sync::{Arc, Mutex, StaticMutex, Condvar};
+    use sync::{Arc, Mutex, Condvar};
     use sync::atomic::{AtomicUsize, Ordering};
     use thread;
 
@@ -461,47 +378,33 @@ mod tests {
     }
 
     #[test]
-    fn smoke_static() {
-        static M: StaticMutex = StaticMutex::new();
-        unsafe {
-            drop(M.lock().unwrap());
-            drop(M.lock().unwrap());
-            M.destroy();
-        }
-    }
-
-    #[test]
     fn lots_and_lots() {
-        static M: StaticMutex = StaticMutex::new();
-        static mut CNT: u32 = 0;
         const J: u32 = 1000;
         const K: u32 = 3;
 
-        fn inc() {
+        let m = Arc::new(Mutex::new(0));
+
+        fn inc(m: &Mutex<u32>) {
             for _ in 0..J {
-                unsafe {
-                    let _g = M.lock().unwrap();
-                    CNT += 1;
-                }
+                *m.lock().unwrap() += 1;
             }
         }
 
         let (tx, rx) = channel();
         for _ in 0..K {
             let tx2 = tx.clone();
-            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            let m2 = m.clone();
+            thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
             let tx2 = tx.clone();
-            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            let m2 = m.clone();
+            thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
         }
 
         drop(tx);
         for _ in 0..2 * K {
             rx.recv().unwrap();
         }
-        assert_eq!(unsafe {CNT}, J * K * 2);
-        unsafe {
-            M.destroy();
-        }
+        assert_eq!(*m.lock().unwrap(), J * K * 2);
     }
 
     #[test]
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index e228d236a3c..54c1fe6c564 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -65,6 +65,7 @@
 // it!
 
 use marker;
+use ptr;
 use sync::atomic::{AtomicUsize, AtomicBool, Ordering};
 use thread::{self, Thread};
 
@@ -101,7 +102,7 @@ unsafe impl Send for Once {}
 
 /// State yielded to the `call_once_force` method which can be used to query
 /// whether the `Once` was previously poisoned or not.
-#[unstable(feature = "once_poison", issue = "31688")]
+#[unstable(feature = "once_poison", issue = "33577")]
 pub struct OnceState {
     poisoned: bool,
 }
@@ -218,8 +219,7 @@ impl Once {
     /// The closure `f` is yielded a structure which can be used to query the
     /// state of this `Once` (whether initialization has previously panicked or
     /// not).
-    /// poisoned or not.
-    #[unstable(feature = "once_poison", issue = "31688")]
+    #[unstable(feature = "once_poison", issue = "33577")]
     pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
         // same as above, just with a different parameter to `call_inner`.
         if self.state.load(Ordering::SeqCst) == COMPLETE {
@@ -298,7 +298,7 @@ impl Once {
                     let mut node = Waiter {
                         thread: Some(thread::current()),
                         signaled: AtomicBool::new(false),
-                        next: 0 as *mut Waiter,
+                        next: ptr::null_mut(),
                     };
                     let me = &mut node as *mut Waiter as usize;
                     assert!(me & STATE_MASK == 0);
@@ -361,7 +361,7 @@ impl OnceState {
     ///
     /// Once an initalization routine for a `Once` has panicked it will forever
     /// indicate to future forced initialization routines that it is poisoned.
-    #[unstable(feature = "once_poison", issue = "31688")]
+    #[unstable(feature = "once_poison", issue = "33577")]
     pub fn poisoned(&self) -> bool {
         self.poisoned
     }
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 09b1b0a939d..65b5686de86 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -38,8 +38,8 @@ use sys_common::rwlock as sys;
 ///
 /// # Poisoning
 ///
-/// RwLocks, like Mutexes, will become poisoned on panics. Note, however, that
-/// an RwLock may only be poisoned if a panic occurs while it is locked
+/// An `RwLock`, like `Mutex`, will become poisoned on a panic. Note, however,
+/// that an `RwLock` may only be poisoned if a panic occurs while it is locked
 /// exclusively (write mode). If a panic occurs in any reader, then the lock
 /// will not be poisoned.
 ///
@@ -67,7 +67,8 @@ use sys_common::rwlock as sys;
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RwLock<T: ?Sized> {
-    inner: Box<StaticRwLock>,
+    inner: Box<sys::RWLock>,
+    poison: poison::Flag,
     data: UnsafeCell<T>,
 }
 
@@ -76,52 +77,12 @@ unsafe impl<T: ?Sized + Send + Sync> Send for RwLock<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 
-/// Structure representing a statically allocated RwLock.
-///
-/// This structure is intended to be used inside of a `static` and will provide
-/// automatic global access as well as lazy initialization. The internal
-/// resources of this RwLock, however, must be manually deallocated.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_rwlock)]
-///
-/// use std::sync::{StaticRwLock, RW_LOCK_INIT};
-///
-/// static LOCK: StaticRwLock = RW_LOCK_INIT;
-///
-/// {
-///     let _g = LOCK.read().unwrap();
-///     // ... shared read access
-/// }
-/// {
-///     let _g = LOCK.write().unwrap();
-///     // ... exclusive write access
-/// }
-/// unsafe { LOCK.destroy() } // free all resources
-/// ```
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-pub struct StaticRwLock {
-    lock: sys::RWLock,
-    poison: poison::Flag,
-}
-
-/// Constant initialization for a statically-initialized rwlock.
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock::new();
-
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
-    __lock: &'a StaticRwLock,
-    __data: &'a T,
+    __lock: &'a RwLock<T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -132,8 +93,7 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
-    __lock: &'a StaticRwLock,
-    __data: &'a mut T,
+    __lock: &'a RwLock<T>,
     __poison: poison::Guard,
 }
 
@@ -152,7 +112,11 @@ impl<T> RwLock<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
-        RwLock { inner: box StaticRwLock::new(), data: UnsafeCell::new(t) }
+        RwLock {
+            inner: box sys::RWLock::new(),
+            poison: poison::Flag::new(),
+            data: UnsafeCell::new(t),
+        }
     }
 }
 
@@ -178,8 +142,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
         unsafe {
-            self.inner.lock.read();
-            RwLockReadGuard::new(&*self.inner, &self.data)
+            self.inner.read();
+            RwLockReadGuard::new(self)
         }
     }
 
@@ -204,8 +168,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
         unsafe {
-            if self.inner.lock.try_read() {
-                Ok(RwLockReadGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_read() {
+                Ok(RwLockReadGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -230,8 +194,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
         unsafe {
-            self.inner.lock.write();
-            RwLockWriteGuard::new(&*self.inner, &self.data)
+            self.inner.write();
+            RwLockWriteGuard::new(self)
         }
     }
 
@@ -256,8 +220,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
         unsafe {
-            if self.inner.lock.try_write() {
-                Ok(RwLockWriteGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_write() {
+                Ok(RwLockWriteGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -272,7 +236,7 @@ impl<T: ?Sized> RwLock<T> {
     #[inline]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn is_poisoned(&self) -> bool {
-        self.inner.poison.get()
+        self.poison.get()
     }
 
     /// Consumes this `RwLock`, returning the underlying data.
@@ -286,21 +250,22 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rwlock_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner StaticRwLock.
+        // `self` so there's no need to lock the inner lock.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `RwLock` impl-s `Drop`, we can't move out of it, so
         // we'll have to destructure it manually instead.
         unsafe {
-            // Like `let RwLock { inner, data } = self`.
-            let (inner, data) = {
-                let RwLock { ref inner, ref data } = self;
-                (ptr::read(inner), ptr::read(data))
+            // Like `let RwLock { inner, poison, data } = self`.
+            let (inner, poison, data) = {
+                let RwLock { ref inner, ref poison, ref data } = self;
+                (ptr::read(inner), ptr::read(poison), ptr::read(data))
             };
             mem::forget(self);
-            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+            inner.destroy();  // Keep in sync with the `Drop` impl.
+            drop(inner);
 
-            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+            poison::map_result(poison.borrow(), |_| data.into_inner())
         }
     }
 
@@ -318,9 +283,9 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rwlock_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner StaticRwLock.
+        // there's no need to lock the inner lock.
         let data = unsafe { &mut *self.data.get() };
-        poison::map_result(self.inner.poison.borrow(), |_| data )
+        poison::map_result(self.poison.borrow(), |_| data)
     }
 }
 
@@ -329,7 +294,7 @@ impl<T: ?Sized> Drop for RwLock<T> {
     #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
         // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
-        unsafe { self.inner.lock.destroy() }
+        unsafe { self.inner.destroy() }
     }
 }
 
@@ -353,223 +318,58 @@ impl<T: Default> Default for RwLock<T> {
     }
 }
 
-struct Dummy(UnsafeCell<()>);
-unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
-
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-impl StaticRwLock {
-    /// Creates a new rwlock.
-    pub const fn new() -> StaticRwLock {
-        StaticRwLock {
-            lock: sys::RWLock::new(),
-            poison: poison::Flag::new(),
-        }
-    }
-
-    /// Locks this rwlock with shared read access, blocking the current thread
-    /// until it can be acquired.
-    ///
-    /// See `RwLock::read`.
-    #[inline]
-    pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> {
-        unsafe {
-            self.lock.read();
-            RwLockReadGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to acquire this lock with shared read access.
-    ///
-    /// See `RwLock::try_read`.
-    #[inline]
-    pub fn try_read(&'static self)
-                    -> TryLockResult<RwLockReadGuard<'static, ()>> {
-        unsafe {
-            if self.lock.try_read(){
-                Ok(RwLockReadGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Locks this rwlock with exclusive write access, blocking the current
-    /// thread until it can be acquired.
-    ///
-    /// See `RwLock::write`.
-    #[inline]
-    pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> {
-        unsafe {
-            self.lock.write();
-            RwLockWriteGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to lock this rwlock with exclusive write access.
-    ///
-    /// See `RwLock::try_write`.
-    #[inline]
-    pub fn try_write(&'static self)
-                     -> TryLockResult<RwLockWriteGuard<'static, ()>> {
-        unsafe {
-            if self.lock.try_write() {
-                Ok(RwLockWriteGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Deallocates all resources associated with this static lock.
-    ///
-    /// This method is unsafe to call as there is no guarantee that there are no
-    /// active users of the lock, and this also doesn't prevent any future users
-    /// of this lock. This method is required to be called to not leak memory on
-    /// all platforms.
-    pub unsafe fn destroy(&'static self) {
-        self.lock.destroy()
-    }
-}
-
 impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
-    unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RwLockReadGuard<'rwlock, T>> {
+    unsafe fn new(lock: &'rwlock RwLock<T>)
+                  -> LockResult<RwLockReadGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |_| {
             RwLockReadGuard {
                 __lock: lock,
-                __data: &*data.get(),
             }
         })
     }
-
-    /// Transform this guard to hold a sub-borrow of the original data.
-    ///
-    /// Applies the supplied closure to the data, returning a new lock
-    /// guard referencing the borrow returned by the closure.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # #![feature(guard_map)]
-    /// # use std::sync::{RwLockReadGuard, RwLock};
-    /// let x = RwLock::new(vec![1, 2]);
-    ///
-    /// let y = RwLockReadGuard::map(x.read().unwrap(), |v| &v[0]);
-    /// assert_eq!(*y, 1);
-    /// ```
-    #[unstable(feature = "guard_map",
-               reason = "recently added, needs RFC for stabilization,
-                         questionable interaction with Condvar",
-               issue = "27746")]
-    #[rustc_deprecated(since = "1.8.0",
-                       reason = "unsound on Mutex because of Condvar and \
-                                 RwLock may also with to be used with Condvar \
-                                 one day")]
-    pub fn map<U: ?Sized, F>(this: Self, cb: F) -> RwLockReadGuard<'rwlock, U>
-        where F: FnOnce(&T) -> &U
-    {
-        let new = RwLockReadGuard {
-            __lock: this.__lock,
-            __data: cb(this.__data)
-        };
-
-        mem::forget(this);
-
-        new
-    }
 }
 
 impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
-    unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RwLockWriteGuard<'rwlock, T>> {
+    unsafe fn new(lock: &'rwlock RwLock<T>)
+                  -> LockResult<RwLockWriteGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
             RwLockWriteGuard {
                 __lock: lock,
-                __data: &mut *data.get(),
                 __poison: guard,
             }
         })
     }
-
-    /// Transform this guard to hold a sub-borrow of the original data.
-    ///
-    /// Applies the supplied closure to the data, returning a new lock
-    /// guard referencing the borrow returned by the closure.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// # #![feature(guard_map)]
-    /// # use std::sync::{RwLockWriteGuard, RwLock};
-    /// let x = RwLock::new(vec![1, 2]);
-    ///
-    /// {
-    ///     let mut y = RwLockWriteGuard::map(x.write().unwrap(), |v| &mut v[0]);
-    ///     assert_eq!(*y, 1);
-    ///
-    ///     *y = 10;
-    /// }
-    ///
-    /// assert_eq!(&**x.read().unwrap(), &[10, 2]);
-    /// ```
-    #[unstable(feature = "guard_map",
-               reason = "recently added, needs RFC for stabilization,
-                         questionable interaction with Condvar",
-               issue = "27746")]
-    #[rustc_deprecated(since = "1.8.0",
-                       reason = "unsound on Mutex because of Condvar and \
-                                 RwLock may also with to be used with Condvar \
-                                 one day")]
-    pub fn map<U: ?Sized, F>(this: Self, cb: F) -> RwLockWriteGuard<'rwlock, U>
-        where F: FnOnce(&mut T) -> &mut U
-    {
-        // Compute the new data while still owning the original lock
-        // in order to correctly poison if the callback panics.
-        let data = unsafe { ptr::read(&this.__data) };
-        let new_data = cb(data);
-
-        // We don't want to unlock the lock by running the destructor of the
-        // original lock, so just read the fields we need and forget it.
-        let (poison, lock) = unsafe {
-            (ptr::read(&this.__poison), ptr::read(&this.__lock))
-        };
-        mem::forget(this);
-
-        RwLockWriteGuard {
-            __lock: lock,
-            __data: new_data,
-            __poison: poison
-        }
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
-    fn deref(&self) -> &T { self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
-    fn deref(&self) -> &T { self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
-    fn deref_mut(&mut self) -> &mut T { self.__data
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe { &mut *self.__lock.data.get() }
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
-        unsafe { self.__lock.lock.read_unlock(); }
+        unsafe { self.__lock.inner.read_unlock(); }
     }
 }
 
@@ -577,7 +377,7 @@ impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
 impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
-        unsafe { self.__lock.lock.write_unlock(); }
+        unsafe { self.__lock.inner.write_unlock(); }
     }
 }
 
@@ -590,7 +390,7 @@ mod tests {
     use rand::{self, Rng};
     use sync::mpsc::channel;
     use thread;
-    use sync::{Arc, RwLock, StaticRwLock, TryLockError, RwLockWriteGuard};
+    use sync::{Arc, RwLock, TryLockError};
     use sync::atomic::{AtomicUsize, Ordering};
 
     #[derive(Eq, PartialEq, Debug)]
@@ -606,31 +406,23 @@ mod tests {
     }
 
     #[test]
-    fn static_smoke() {
-        static R: StaticRwLock = StaticRwLock::new();
-        drop(R.read().unwrap());
-        drop(R.write().unwrap());
-        drop((R.read().unwrap(), R.read().unwrap()));
-        drop(R.write().unwrap());
-        unsafe { R.destroy(); }
-    }
-
-    #[test]
     fn frob() {
-        static R: StaticRwLock = StaticRwLock::new();
         const N: usize = 10;
         const M: usize = 1000;
 
+        let r = Arc::new(RwLock::new(()));
+
         let (tx, rx) = channel::<()>();
         for _ in 0..N {
             let tx = tx.clone();
-            thread::spawn(move|| {
+            let r = r.clone();
+            thread::spawn(move || {
                 let mut rng = rand::thread_rng();
                 for _ in 0..M {
                     if rng.gen_weighted_bool(N) {
-                        drop(R.write().unwrap());
+                        drop(r.write().unwrap());
                     } else {
-                        drop(R.read().unwrap());
+                        drop(r.read().unwrap());
                     }
                 }
                 drop(tx);
@@ -638,7 +430,6 @@ mod tests {
         }
         drop(tx);
         let _ = rx.recv();
-        unsafe { R.destroy(); }
     }
 
     #[test]
@@ -838,20 +629,4 @@ mod tests {
             Ok(x) => panic!("get_mut of poisoned RwLock is Ok: {:?}", x),
         }
     }
-
-    #[test]
-    fn test_rwlock_write_map_poison() {
-        let rwlock = Arc::new(RwLock::new(vec![1, 2]));
-        let rwlock2 = rwlock.clone();
-
-        thread::spawn(move || {
-            let _ = RwLockWriteGuard::map::<usize, _>(rwlock2.write().unwrap(), |_| panic!());
-        }).join().unwrap_err();
-
-        match rwlock.read() {
-            Ok(r) => panic!("Read lock on poisioned RwLock is Ok: {:?}", &*r),
-            Err(_) => {}
-        };
-    }
 }
-
diff --git a/src/libstd/sys/common/args.rs b/src/libstd/sys/common/args.rs
index 58417540664..e877391fb8b 100644
--- a/src/libstd/sys/common/args.rs
+++ b/src/libstd/sys/common/args.rs
@@ -48,32 +48,36 @@ mod imp {
     use mem;
     use ffi::CStr;
 
-    use sync::StaticMutex;
+    use sys_common::mutex::Mutex;
 
     static mut GLOBAL_ARGS_PTR: usize = 0;
-    static LOCK: StaticMutex = StaticMutex::new();
+    static LOCK: Mutex = Mutex::new();
 
     pub unsafe fn init(argc: isize, argv: *const *const u8) {
         let args = (0..argc).map(|i| {
             CStr::from_ptr(*argv.offset(i) as *const c_char).to_bytes().to_vec()
         }).collect();
 
-        let _guard = LOCK.lock();
+        LOCK.lock();
         let ptr = get_global_ptr();
         assert!((*ptr).is_none());
         (*ptr) = Some(box args);
+        LOCK.unlock();
     }
 
     pub unsafe fn cleanup() {
-        let _guard = LOCK.lock();
+        LOCK.lock();
         *get_global_ptr() = None;
+        LOCK.unlock();
     }
 
     pub fn clone() -> Option<Vec<Vec<u8>>> {
-        let _guard = LOCK.lock();
         unsafe {
+            LOCK.lock();
             let ptr = get_global_ptr();
-            (*ptr).as_ref().map(|s| (**s).clone())
+            let ret = (*ptr).as_ref().map(|s| (**s).clone());
+            LOCK.unlock();
+            return ret
         }
     }
 
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs
index 6f185437e50..4c23ceb63f2 100644
--- a/src/libstd/sys/common/backtrace.rs
+++ b/src/libstd/sys/common/backtrace.rs
@@ -170,7 +170,9 @@ pub fn demangle(writer: &mut Write, s: &str) -> io::Result<()> {
                         "$u20$", => b" ",
                         "$u27$", => b"'",
                         "$u5b$", => b"[",
-                        "$u5d$", => b"]"
+                        "$u5d$", => b"]",
+                        "$u7b$", => b"{",
+                        "$u7d$", => b"}"
                     )
                 } else {
                     let idx = match rest.find('$') {
diff --git a/src/libstd/sys/common/dwarf/eh.rs b/src/libstd/sys/common/dwarf/eh.rs
deleted file mode 100644
index 319be245bde..00000000000
--- a/src/libstd/sys/common/dwarf/eh.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2015 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.
-
-//! Parsing of GCC-style Language-Specific Data Area (LSDA)
-//! For details see:
-//!   http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html
-//!   http://mentorembedded.github.io/cxx-abi/exceptions.pdf
-//!   http://www.airs.com/blog/archives/460
-//!   http://www.airs.com/blog/archives/464
-//!
-//! A reference implementation may be found in the GCC source tree
-//! (<root>/libgcc/unwind-c.c as of this writing)
-
-#![allow(non_upper_case_globals)]
-#![allow(unused)]
-
-use prelude::v1::*;
-use sys_common::dwarf::DwarfReader;
-use core::mem;
-
-pub const DW_EH_PE_omit     : u8 = 0xFF;
-pub const DW_EH_PE_absptr   : u8 = 0x00;
-
-pub const DW_EH_PE_uleb128  : u8 = 0x01;
-pub const DW_EH_PE_udata2   : u8 = 0x02;
-pub const DW_EH_PE_udata4   : u8 = 0x03;
-pub const DW_EH_PE_udata8   : u8 = 0x04;
-pub const DW_EH_PE_sleb128  : u8 = 0x09;
-pub const DW_EH_PE_sdata2   : u8 = 0x0A;
-pub const DW_EH_PE_sdata4   : u8 = 0x0B;
-pub const DW_EH_PE_sdata8   : u8 = 0x0C;
-
-pub const DW_EH_PE_pcrel    : u8 = 0x10;
-pub const DW_EH_PE_textrel  : u8 = 0x20;
-pub const DW_EH_PE_datarel  : u8 = 0x30;
-pub const DW_EH_PE_funcrel  : u8 = 0x40;
-pub const DW_EH_PE_aligned  : u8 = 0x50;
-
-pub const DW_EH_PE_indirect : u8 = 0x80;
-
-#[derive(Copy, Clone)]
-pub struct EHContext {
-    pub ip: usize,         // Current instruction pointer
-    pub func_start: usize, // Address of the current function
-    pub text_start: usize, // Address of the code section
-    pub data_start: usize, // Address of the data section
-}
-
-pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
-                               -> Option<usize> {
-    if lsda.is_null() {
-        return None;
-    }
-
-    let func_start = context.func_start;
-    let mut reader = DwarfReader::new(lsda);
-
-    let start_encoding = reader.read::<u8>();
-    // base address for landing pad offsets
-    let lpad_base = if start_encoding != DW_EH_PE_omit {
-        read_encoded_pointer(&mut reader, context, start_encoding)
-    } else {
-        func_start
-    };
-
-    let ttype_encoding = reader.read::<u8>();
-    if ttype_encoding != DW_EH_PE_omit {
-        // Rust doesn't analyze exception types, so we don't care about the type table
-        reader.read_uleb128();
-    }
-
-    let call_site_encoding = reader.read::<u8>();
-    let call_site_table_length = reader.read_uleb128();
-    let action_table = reader.ptr.offset(call_site_table_length as isize);
-    // Return addresses point 1 byte past the call instruction, which could
-    // be in the next IP range.
-    let ip = context.ip-1;
-
-    while reader.ptr < action_table {
-        let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding);
-        let cs_len = read_encoded_pointer(&mut reader, context, call_site_encoding);
-        let cs_lpad = read_encoded_pointer(&mut reader, context, call_site_encoding);
-        let cs_action = reader.read_uleb128();
-        // Callsite table is sorted by cs_start, so if we've passed the ip, we
-        // may stop searching.
-        if ip < func_start + cs_start {
-            break
-        }
-        if ip < func_start + cs_start + cs_len {
-            if cs_lpad != 0 {
-                return Some(lpad_base + cs_lpad);
-            } else {
-                return None;
-            }
-        }
-    }
-    // IP range not found: gcc's C++ personality calls terminate() here,
-    // however the rest of the languages treat this the same as cs_lpad == 0.
-    // We follow this suit.
-    None
-}
-
-#[inline]
-fn round_up(unrounded: usize, align: usize) -> usize {
-    assert!(align.is_power_of_two());
-    (unrounded + align - 1) & !(align - 1)
-}
-
-unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
-                               context: &EHContext,
-                               encoding: u8) -> usize {
-    assert!(encoding != DW_EH_PE_omit);
-
-    // DW_EH_PE_aligned implies it's an absolute pointer value
-    if encoding == DW_EH_PE_aligned {
-        reader.ptr = round_up(reader.ptr as usize,
-                              mem::size_of::<usize>()) as *const u8;
-        return reader.read::<usize>();
-    }
-
-    let mut result = match encoding & 0x0F {
-        DW_EH_PE_absptr => reader.read::<usize>(),
-        DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
-        DW_EH_PE_udata2 => reader.read::<u16>() as usize,
-        DW_EH_PE_udata4 => reader.read::<u32>() as usize,
-        DW_EH_PE_udata8 => reader.read::<u64>() as usize,
-        DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
-        DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
-        DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
-        DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
-        _ => panic!()
-    };
-
-    result += match encoding & 0x70 {
-        DW_EH_PE_absptr => 0,
-        // relative to address of the encoded value, despite the name
-        DW_EH_PE_pcrel => reader.ptr as usize,
-        DW_EH_PE_textrel => { assert!(context.text_start != 0);
-                              context.text_start },
-        DW_EH_PE_datarel => { assert!(context.data_start != 0);
-                              context.data_start },
-        DW_EH_PE_funcrel => { assert!(context.func_start != 0);
-                              context.func_start },
-        _ => panic!()
-    };
-
-    if encoding & DW_EH_PE_indirect != 0 {
-        result = *(result as *const usize);
-    }
-
-    result
-}
diff --git a/src/libstd/sys/common/dwarf/mod.rs b/src/libstd/sys/common/dwarf/mod.rs
deleted file mode 100644
index 822826bcc83..00000000000
--- a/src/libstd/sys/common/dwarf/mod.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2015 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.
-
-//! Utilities for parsing DWARF-encoded data streams.
-//! See http://www.dwarfstd.org,
-//! DWARF-4 standard, Section 7 - "Data Representation"
-
-// This module is used only by x86_64-pc-windows-gnu for now, but we
-// are compiling it everywhere to avoid regressions.
-#![allow(unused)]
-
-pub mod eh;
-
-use prelude::v1::*;
-use core::mem;
-
-pub struct DwarfReader {
-    pub ptr : *const u8
-}
-
-#[repr(C,packed)]
-struct Unaligned<T>(T);
-
-impl DwarfReader {
-
-    pub fn new(ptr : *const u8) -> DwarfReader {
-        DwarfReader {
-            ptr : ptr
-        }
-    }
-
-    // DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
-    // on a 4-byte boundary. This may cause problems on platforms with strict
-    // alignment requirements. By wrapping data in a "packed" struct, we are
-    // telling the backend to generate "misalignment-safe" code.
-    pub unsafe fn read<T:Copy>(&mut self) -> T {
-        let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
-        self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
-        result
-    }
-
-    // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
-    // Length Data".
-    pub unsafe fn read_uleb128(&mut self) -> u64 {
-        let mut shift : usize = 0;
-        let mut result : u64 = 0;
-        let mut byte : u8;
-        loop {
-            byte = self.read::<u8>();
-            result |= ((byte & 0x7F) as u64) << shift;
-            shift += 7;
-            if byte & 0x80 == 0 {
-                break;
-            }
-        }
-        result
-    }
-
-    pub unsafe fn read_sleb128(&mut self) -> i64 {
-        let mut shift : usize = 0;
-        let mut result : u64 = 0;
-        let mut byte : u8;
-        loop {
-            byte = self.read::<u8>();
-            result |= ((byte & 0x7F) as u64) << shift;
-            shift += 7;
-            if byte & 0x80 == 0 {
-                break;
-            }
-        }
-        // sign-extend
-        if shift < 8 * mem::size_of::<u64>() && (byte & 0x40) != 0 {
-            result |= (!0 as u64) << shift;
-        }
-        result as i64
-    }
-}
-
-#[test]
-fn dwarf_reader() {
-    let encoded: &[u8] = &[1,
-                           2, 3,
-                           4, 5, 6, 7,
-                           0xE5, 0x8E, 0x26,
-                           0x9B, 0xF1, 0x59,
-                           0xFF, 0xFF];
-
-    let mut reader = DwarfReader::new(encoded.as_ptr());
-
-    unsafe {
-        assert!(reader.read::<u8>() == u8::to_be(1u8));
-        assert!(reader.read::<u16>() == u16::to_be(0x0203));
-        assert!(reader.read::<u32>() == u32::to_be(0x04050607));
-
-        assert!(reader.read_uleb128() == 624485);
-        assert!(reader.read_sleb128() == -624485);
-
-        assert!(reader.read::<i8>() == i8::to_be(-1));
-    }
-}
diff --git a/src/libstd/sys/common/gnu/libbacktrace.rs b/src/libstd/sys/common/gnu/libbacktrace.rs
index db719ccce61..b5802afc109 100644
--- a/src/libstd/sys/common/gnu/libbacktrace.rs
+++ b/src/libstd/sys/common/gnu/libbacktrace.rs
@@ -15,7 +15,6 @@ use sys_common::backtrace::{output, output_fileline};
 
 pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
              symaddr: *mut libc::c_void) -> io::Result<()> {
-    use env;
     use ffi::CStr;
     use ptr;
 
@@ -110,46 +109,22 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
     // that is calculated the first time this is requested. Remember that
     // backtracing all happens serially (one global lock).
     //
-    // An additionally oddity in this function is that we initialize the
-    // filename via self_exe_name() to pass to libbacktrace. It turns out
-    // that on Linux libbacktrace seamlessly gets the filename of the
-    // current executable, but this fails on freebsd. by always providing
-    // it, we make sure that libbacktrace never has a reason to not look up
-    // the symbols. The libbacktrace API also states that the filename must
-    // be in "permanent memory", so we copy it to a static and then use the
-    // static as the pointer.
+    // Things don't work so well on not-Linux since libbacktrace can't track
+    // down that executable this is. We at one point used env::current_exe but
+    // it turns out that there are some serious security issues with that
+    // approach.
     //
-    // FIXME: We also call self_exe_name() on DragonFly BSD. I haven't
-    //        tested if this is required or not.
+    // Specifically, on certain platforms like BSDs, a malicious actor can cause
+    // an arbitrary file to be placed at the path returned by current_exe.
+    // libbacktrace does not behave defensively in the presence of ill-formed
+    // DWARF information, and has been demonstrated to segfault in at least one
+    // case. There is no evidence at the moment to suggest that a more carefully
+    // constructed file can't cause arbitrary code execution. As a result of all
+    // of this, we don't hint libbacktrace with the path to the current process.
     unsafe fn init_state() -> *mut backtrace_state {
         static mut STATE: *mut backtrace_state = ptr::null_mut();
-        static mut LAST_FILENAME: [libc::c_char; 256] = [0; 256];
         if !STATE.is_null() { return STATE }
-        let selfname = if cfg!(target_os = "freebsd") ||
-            cfg!(target_os = "dragonfly") ||
-            cfg!(target_os = "bitrig") ||
-            cfg!(target_os = "openbsd") ||
-            cfg!(target_os = "windows") {
-                env::current_exe().ok()
-            } else {
-                None
-            };
-        let filename = match selfname.as_ref().and_then(|s| s.to_str()) {
-            Some(path) => {
-                let bytes = path.as_bytes();
-                if bytes.len() < LAST_FILENAME.len() {
-                    let i = bytes.iter();
-                    for (slot, val) in LAST_FILENAME.iter_mut().zip(i) {
-                        *slot = *val as libc::c_char;
-                    }
-                    LAST_FILENAME.as_ptr()
-                } else {
-                    ptr::null()
-                }
-            }
-            None => ptr::null(),
-        };
-        STATE = backtrace_create_state(filename, 0, error_cb,
+        STATE = backtrace_create_state(ptr::null(), 0, error_cb,
                                        ptr::null_mut());
         STATE
     }
diff --git a/src/libstd/sys/common/libunwind.rs b/src/libstd/sys/common/libunwind.rs
deleted file mode 100644
index c1e9782852a..00000000000
--- a/src/libstd/sys/common/libunwind.rs
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014-2015 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_upper_case_globals)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case)]
-#![allow(dead_code)] // these are just bindings
-
-#[cfg(any(not(target_arch = "arm"), target_os = "ios"))]
-pub use self::_Unwind_Action::*;
-#[cfg(target_arch = "arm")]
-pub use self::_Unwind_State::*;
-pub use self::_Unwind_Reason_Code::*;
-
-use libc;
-
-#[cfg(any(not(target_arch = "arm"), target_os = "ios"))]
-#[repr(C)]
-#[derive(Copy, Clone)]
-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)]
-#[derive(Copy, Clone)]
-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)]
-#[derive(Copy, Clone)]
-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 const unwinder_private_data_size: usize = 5;
-
-#[cfg(target_arch = "x86_64")]
-pub const unwinder_private_data_size: usize = 6;
-
-#[cfg(all(target_arch = "arm", not(target_os = "ios")))]
-pub const unwinder_private_data_size: usize = 20;
-
-#[cfg(all(target_arch = "arm", target_os = "ios"))]
-pub const unwinder_private_data_size: usize = 5;
-
-#[cfg(target_arch = "aarch64")]
-pub const unwinder_private_data_size: usize = 2;
-
-#[cfg(target_arch = "mips")]
-pub const unwinder_private_data_size: usize = 2;
-
-#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
-pub const unwinder_private_data_size: usize = 2;
-
-#[cfg(target_arch = "asmjs")]
-// FIXME: Copied from arm. Need to confirm.
-pub const unwinder_private_data_size: usize = 20;
-
-#[repr(C)]
-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: *mut _Unwind_Exception);
-
-#[cfg_attr(any(all(target_os = "linux", not(target_env = "musl")),
-               target_os = "freebsd",
-               target_os = "solaris",
-               all(target_os = "linux",
-                   target_env = "musl",
-                   not(target_arch = "x86"),
-                   not(target_arch = "x86_64"))),
-           link(name = "gcc_s"))]
-#[cfg_attr(all(target_os = "linux",
-               target_env = "musl",
-               any(target_arch = "x86", target_arch = "x86_64"),
-               not(test)),
-           link(name = "unwind", kind = "static"))]
-#[cfg_attr(any(target_os = "android", target_os = "openbsd"),
-           link(name = "gcc"))]
-#[cfg_attr(all(target_os = "netbsd", not(target_vendor = "rumprun")),
-           link(name = "gcc"))]
-#[cfg_attr(all(target_os = "netbsd", target_vendor = "rumprun"),
-           link(name = "unwind"))]
-#[cfg_attr(target_os = "dragonfly",
-           link(name = "gcc_pic"))]
-#[cfg_attr(target_os = "bitrig",
-           link(name = "c++abi"))]
-#[cfg_attr(all(target_os = "windows", target_env="gnu"),
-           link(name = "gcc_eh"))]
-extern "C" {
-    // iOS on armv7 uses SjLj exceptions and requires to link
-    // against corresponding routine (..._SjLj_...)
-    #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
-    #[unwind]
-    pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
-                                  -> _Unwind_Reason_Code;
-
-    #[cfg(all(target_os = "ios", target_arch = "arm"))]
-    #[unwind]
-    fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception)
-                                   -> _Unwind_Reason_Code;
-
-    pub fn _Unwind_DeleteException(exception: *mut _Unwind_Exception);
-
-    #[unwind]
-    pub fn _Unwind_Resume(exception: *mut _Unwind_Exception) -> !;
-}
-
-// ... and now we just providing access to SjLj counterspart
-// through a standard name to hide those details from others
-// (see also comment above regarding _Unwind_RaiseException)
-#[cfg(all(target_os = "ios", target_arch = "arm"))]
-#[inline(always)]
-pub unsafe fn _Unwind_RaiseException(exc: *mut _Unwind_Exception)
-                                     -> _Unwind_Reason_Code {
-    _Unwind_SjLj_RaiseException(exc)
-}
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index 56628a4c754..c9279883ae5 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -30,9 +30,7 @@ pub mod args;
 pub mod at_exit_imp;
 pub mod backtrace;
 pub mod condvar;
-pub mod dwarf;
 pub mod io;
-pub mod libunwind;
 pub mod mutex;
 pub mod net;
 pub mod poison;
@@ -41,7 +39,6 @@ pub mod rwlock;
 pub mod thread;
 pub mod thread_info;
 pub mod thread_local;
-pub mod unwind;
 pub mod util;
 pub mod wtf8;
 
diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs
index 5a6dfe7fb1a..7a2183c522f 100644
--- a/src/libstd/sys/common/mutex.rs
+++ b/src/libstd/sys/common/mutex.rs
@@ -27,6 +27,12 @@ impl Mutex {
     /// first used with any of the functions below.
     pub const fn new() -> Mutex { Mutex(imp::Mutex::new()) }
 
+    /// Prepare the mutex for use.
+    ///
+    /// This should be called once the mutex is at a stable memory address.
+    #[inline]
+    pub unsafe fn init(&mut self) { self.0.init() }
+
     /// Locks the mutex blocking the current thread until it is available.
     ///
     /// Behavior is undefined if the mutex has been moved between this and any
diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs
index 54b9b466c42..442618c55b3 100644
--- a/src/libstd/sys/common/net.rs
+++ b/src/libstd/sys/common/net.rs
@@ -25,19 +25,23 @@ use time::Duration;
 
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
           target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd"))]
+          target_os = "openbsd", target_os = "netbsd",
+          target_os = "solaris"))]
 use sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
               target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd")))]
+              target_os = "openbsd", target_os = "netbsd",
+              target_os = "solaris")))]
 use sys::net::netc::IPV6_ADD_MEMBERSHIP;
 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
           target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd"))]
+          target_os = "openbsd", target_os = "netbsd",
+          target_os = "solaris"))]
 use sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
               target_os = "ios", target_os = "macos",
-          target_os = "openbsd", target_os = "netbsd")))]
+              target_os = "openbsd", target_os = "netbsd",
+              target_os = "solaris")))]
 use sys::net::netc::IPV6_DROP_MEMBERSHIP;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -119,14 +123,22 @@ pub struct LookupHost {
 }
 
 impl Iterator for LookupHost {
-    type Item = io::Result<SocketAddr>;
-    fn next(&mut self) -> Option<io::Result<SocketAddr>> {
-        unsafe {
-            if self.cur.is_null() { return None }
-            let ret = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr),
-                                       (*self.cur).ai_addrlen as usize);
-            self.cur = (*self.cur).ai_next as *mut c::addrinfo;
-            Some(ret)
+    type Item = SocketAddr;
+    fn next(&mut self) -> Option<SocketAddr> {
+        loop {
+            unsafe {
+                let cur = match self.cur.as_ref() {
+                    None => return None,
+                    Some(c) => c,
+                };
+                self.cur = cur.ai_next;
+                match sockaddr_to_addr(mem::transmute(cur.ai_addr),
+                                       cur.ai_addrlen as usize)
+                {
+                    Ok(addr) => return Some(addr),
+                    Err(_) => continue,
+                }
+            }
         }
     }
 }
@@ -144,9 +156,19 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     init();
 
     let c_host = CString::new(host)?;
+    let hints = c::addrinfo {
+        ai_flags: 0,
+        ai_family: 0,
+        ai_socktype: c::SOCK_STREAM,
+        ai_protocol: 0,
+        ai_addrlen: 0,
+        ai_addr: ptr::null_mut(),
+        ai_canonname: ptr::null_mut(),
+        ai_next: ptr::null_mut()
+    };
     let mut res = ptr::null_mut();
     unsafe {
-        cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
+        cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints,
                                &mut res))?;
         Ok(LookupHost { original: res, cur: res })
     }
@@ -583,3 +605,22 @@ impl fmt::Debug for UdpSocket {
             .finish()
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use prelude::v1::*;
+
+    use super::*;
+    use collections::HashMap;
+
+    #[test]
+    fn no_lookup_host_duplicates() {
+        let mut addrs = HashMap::new();
+        let lh = match lookup_host("localhost") {
+            Ok(lh) => lh,
+            Err(e) => panic!("couldn't resolve `localhost': {}", e)
+        };
+        let _na = lh.map(|sa| *addrs.entry(sa).or_insert(0) += 1).count();
+        assert!(addrs.values().filter(|&&v| v > 1).count() == 0);
+    }
+}
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 83780a31cce..55212bf35d6 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -8,22 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use cell::Cell;
 use error::{Error};
 use fmt;
 use marker::Reflect;
+use sync::atomic::{AtomicBool, Ordering};
 use thread;
 
-pub struct Flag { failed: Cell<bool> }
+pub struct Flag { failed: AtomicBool }
 
-// This flag is only ever accessed with a lock previously held. Note that this
-// a totally private structure.
-unsafe impl Send for Flag {}
-unsafe impl Sync for Flag {}
+// Note that the Ordering uses to access the `failed` field of `Flag` below is
+// always `Relaxed`, and that's because this isn't actually protecting any data,
+// it's just a flag whether we've panicked or not.
+//
+// The actual location that this matters is when a mutex is **locked** which is
+// where we have external synchronization ensuring that we see memory
+// reads/writes to this flag.
+//
+// As a result, if it matters, we should see the correct value for `failed` in
+// all cases.
 
 impl Flag {
     pub const fn new() -> Flag {
-        Flag { failed: Cell::new(false) }
+        Flag { failed: AtomicBool::new(false) }
     }
 
     #[inline]
@@ -39,13 +45,13 @@ impl Flag {
     #[inline]
     pub fn done(&self, guard: &Guard) {
         if !guard.panicking && thread::panicking() {
-            self.failed.set(true);
+            self.failed.store(true, Ordering::Relaxed);
         }
     }
 
     #[inline]
     pub fn get(&self) -> bool {
-        self.failed.get()
+        self.failed.load(Ordering::Relaxed)
     }
 }
 
diff --git a/src/libstd/sys/common/unwind/gcc.rs b/src/libstd/sys/common/unwind/gcc.rs
deleted file mode 100644
index da7a340af35..00000000000
--- a/src/libstd/sys/common/unwind/gcc.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright 2015 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(private_no_mangle_fns)]
-
-use prelude::v1::*;
-
-use any::Any;
-use sys_common::libunwind as uw;
-
-struct Exception {
-    uwe: uw::_Unwind_Exception,
-    cause: Option<Box<Any + Send + 'static>>,
-}
-
-pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
-    let exception: Box<_> = box Exception {
-        uwe: uw::_Unwind_Exception {
-            exception_class: rust_exception_class(),
-            exception_cleanup: exception_cleanup,
-            private: [0; uw::unwinder_private_data_size],
-        },
-        cause: Some(data),
-    };
-    let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
-    let error = uw::_Unwind_RaiseException(exception_param);
-    rtabort!("Could not unwind stack, error = {}", error as isize);
-
-    extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
-                                exception: *mut uw::_Unwind_Exception) {
-        unsafe {
-            let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
-        }
-    }
-}
-
-pub fn payload() -> *mut u8 {
-    0 as *mut u8
-}
-
-pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
-    let my_ep = ptr as *mut Exception;
-    let cause = (*my_ep).cause.take();
-    uw::_Unwind_DeleteException(ptr as *mut _);
-    cause.unwrap()
-}
-
-// 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 thread's stack.
-// So we have two versions of the personality routine:
-// - 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.
-//
-// See also: rustc_trans::trans::intrinsic::trans_gnu_try
-
-#[cfg(all(not(target_arch = "arm"),
-          not(all(windows, target_arch = "x86_64")),
-          not(test)))]
-pub mod eabi {
-    use sys_common::libunwind as uw;
-    use libc::c_int;
-
-    extern {
-        fn __gcc_personality_v0(version: c_int,
-                                actions: uw::_Unwind_Action,
-                                exception_class: uw::_Unwind_Exception_Class,
-                                ue_header: *mut uw::_Unwind_Exception,
-                                context: *mut uw::_Unwind_Context)
-            -> uw::_Unwind_Reason_Code;
-    }
-
-    #[lang = "eh_personality"]
-    #[no_mangle]
-    extern fn rust_eh_personality(
-        version: c_int,
-        actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        unsafe {
-            __gcc_personality_v0(version, actions, exception_class, ue_header,
-                                 context)
-        }
-    }
-
-    #[lang = "eh_personality_catch"]
-    #[no_mangle]
-    pub extern fn rust_eh_personality_catch(
-        version: c_int,
-        actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut 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)
-            }
-        }
-    }
-}
-
-// iOS on armv7 is using SjLj exceptions and therefore requires to use
-// a specialized personality routine: __gcc_personality_sj0
-
-#[cfg(all(target_os = "ios", target_arch = "arm", not(test)))]
-pub mod eabi {
-    use sys_common::libunwind as uw;
-    use libc::c_int;
-
-    extern {
-        fn __gcc_personality_sj0(version: c_int,
-                                actions: uw::_Unwind_Action,
-                                exception_class: uw::_Unwind_Exception_Class,
-                                ue_header: *mut uw::_Unwind_Exception,
-                                context: *mut uw::_Unwind_Context)
-            -> uw::_Unwind_Reason_Code;
-    }
-
-    #[lang = "eh_personality"]
-    #[no_mangle]
-    pub extern fn rust_eh_personality(
-        version: c_int,
-        actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        unsafe {
-            __gcc_personality_sj0(version, actions, exception_class, ue_header,
-                                  context)
-        }
-    }
-
-    #[lang = "eh_personality_catch"]
-    #[no_mangle]
-    pub extern fn rust_eh_personality_catch(
-        version: c_int,
-        actions: uw::_Unwind_Action,
-        exception_class: uw::_Unwind_Exception_Class,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut 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_sj0(version, actions, exception_class, ue_header,
-                                      context)
-            }
-        }
-    }
-}
-
-
-// ARM EHABI uses a slightly different personality routine signature,
-// but otherwise works the same.
-#[cfg(all(target_arch = "arm", not(target_os = "ios"), not(test)))]
-pub mod eabi {
-    use sys_common::libunwind as uw;
-    use libc::c_int;
-
-    extern {
-        fn __gcc_personality_v0(state: uw::_Unwind_State,
-                                ue_header: *mut uw::_Unwind_Exception,
-                                context: *mut uw::_Unwind_Context)
-            -> uw::_Unwind_Reason_Code;
-    }
-
-    #[lang = "eh_personality"]
-    #[no_mangle]
-    extern fn rust_eh_personality(
-        state: uw::_Unwind_State,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        unsafe {
-            __gcc_personality_v0(state, ue_header, context)
-        }
-    }
-
-    #[lang = "eh_personality_catch"]
-    #[no_mangle]
-    pub extern fn rust_eh_personality_catch(
-        state: uw::_Unwind_State,
-        ue_header: *mut uw::_Unwind_Exception,
-        context: *mut uw::_Unwind_Context
-    ) -> uw::_Unwind_Reason_Code
-    {
-        // Backtraces on ARM will call the personality routine with
-        // state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
-        // we want to continue unwinding the stack, otherwise all our backtraces
-        // would end at __rust_try.
-        if (state as c_int & uw::_US_ACTION_MASK as c_int)
-                           == uw::_US_VIRTUAL_UNWIND_FRAME as c_int
-               && (state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 { // search phase
-            uw::_URC_HANDLER_FOUND // catch!
-        }
-        else { // cleanup phase
-            unsafe {
-                __gcc_personality_v0(state, ue_header, context)
-            }
-        }
-    }
-}
-
-// See docs in the `unwind` module.
-#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu", not(test)))]
-#[lang = "eh_unwind_resume"]
-#[unwind]
-unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
-    uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
-}
-
-#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
-pub mod eh_frame_registry {
-    // The implementation of stack unwinding is (for now) deferred to libgcc_eh, however Rust
-    // crates use these Rust-specific entry points to avoid potential clashes with GCC runtime.
-    // See also: rtbegin.rs, `unwind` module.
-
-    #[link(name = "gcc_eh")]
-    #[cfg(not(cargobuild))]
-    extern {}
-
-    extern {
-        fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
-        fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
-    }
-    #[cfg(not(test))]
-    #[no_mangle]
-    #[unstable(feature = "libstd_sys_internals", issue = "0")]
-    pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8,
-                                                 object: *mut u8) {
-        __register_frame_info(eh_frame_begin, object);
-    }
-    #[cfg(not(test))]
-    #[no_mangle]
-    #[unstable(feature = "libstd_sys_internals", issue = "0")]
-    pub  unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
-                                                   object: *mut u8) {
-        __deregister_frame_info(eh_frame_begin, object);
-    }
-}
diff --git a/src/libstd/sys/common/unwind/mod.rs b/src/libstd/sys/common/unwind/mod.rs
deleted file mode 100644
index 527c2e63030..00000000000
--- a/src/libstd/sys/common/unwind/mod.rs
+++ /dev/null
@@ -1,241 +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 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://mentorembedded.github.io/cxx-abi/abi-eh.html
-//!     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, the unwinder invokes each personality routine again.
-//! This time it decides which (if any) cleanup code needs to be run for
-//! the current stack frame.  If so, the control is transferred to a special branch
-//! in the function body, the "landing pad", which invokes destructors, frees memory,
-//! etc.  At the end of the landing pad, control is transferred back to the unwinder
-//! and unwinding resumes.
-//!
-//! Once stack has been unwound down to the handler frame level, unwinding stops
-//! and the last personality routine transfers control to the catch block.
-//!
-//! ## `eh_personality` and `eh_unwind_resume`
-//!
-//! These language items are used by the compiler when generating unwind info.
-//! The first one is the personality routine described above.  The second one
-//! allows compilation target to customize the process of resuming unwind at the
-//! end of the landing pads.  `eh_unwind_resume` is used only if `custom_unwind_resume`
-//! flag in the target options is set.
-//!
-//! ## Frame unwind info registration
-//!
-//! Each module's image contains a frame unwind info section (usually ".eh_frame").
-//! When a module is loaded/unloaded into the process, the unwinder must be informed
-//! about the location of this section in memory. The methods of achieving that vary
-//! by the platform.
-//! On some (e.g. Linux), the unwinder can discover unwind info sections on its own
-//! (by dynamically enumerating currently loaded modules via the dl_iterate_phdr() API
-//! and finding their ".eh_frame" sections);
-//! Others, like Windows, require modules to actively register their unwind info
-//! sections via unwinder API (see `rust_eh_register_frames`/`rust_eh_unregister_frames`).
-
-#![allow(dead_code)]
-#![allow(unused_imports)]
-
-use prelude::v1::*;
-
-use any::Any;
-use boxed;
-use cmp;
-use panicking::{self,PANIC_COUNT};
-use fmt;
-use intrinsics;
-use mem;
-use sync::atomic::{self, Ordering};
-use sys_common::mutex::Mutex;
-
-// The actual unwinding implementation is cfg'd here, and we've got two current
-// implementations. One goes through SEH on Windows and the other goes through
-// libgcc via the libunwind-like API.
-
-// *-pc-windows-msvc
-#[cfg(target_env = "msvc")]
-#[path = "seh.rs"] #[doc(hidden)]
-pub mod imp;
-
-// x86_64-pc-windows-gnu
-#[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))]
-#[path = "seh64_gnu.rs"] #[doc(hidden)]
-pub mod imp;
-
-// i686-pc-windows-gnu and all others
-#[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))]
-#[path = "gcc.rs"] #[doc(hidden)]
-pub mod imp;
-
-/// Invoke a closure, capturing the cause of panic if one occurs.
-///
-/// This function will return `Ok(())` if the closure did not panic, and will
-/// return `Err(cause)` if the closure panics. The `cause` returned is the
-/// object with which panic 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
-///   thread, 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 thread itself.
-///
-/// * It is not sound to trigger unwinding while already unwinding. Rust threads
-///   have runtime checks in place to ensure this invariant, but it is not
-///   guaranteed that a rust thread 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: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
-    let mut f = Some(f);
-    return inner_try(try_fn::<F>, &mut f as *mut _ as *mut u8);
-
-    fn try_fn<F: FnOnce()>(opt_closure: *mut u8) {
-        let opt_closure = opt_closure as *mut Option<F>;
-        unsafe { (*opt_closure).take().unwrap()(); }
-    }
-}
-
-unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
-                    -> Result<(), Box<Any + Send>> {
-    PANIC_COUNT.with(|s| {
-        let prev = s.get();
-        s.set(0);
-
-        // The "payload" here is a platform-specific region of memory which is
-        // used to transmit information about the exception being thrown from
-        // the point-of-throw back to this location.
-        //
-        // A pointer to this data is passed to the `try` intrinsic itself,
-        // allowing this function, the `try` intrinsic, imp::payload(), and
-        // imp::cleanup() to all work in concert to transmit this information.
-        //
-        // More information about what this pointer actually is can be found in
-        // each implementation as well as browsing the compiler source itself.
-        let mut payload = imp::payload();
-        let r = intrinsics::try(f, data, &mut payload as *mut _ as *mut _);
-        s.set(prev);
-        if r == 0 {
-            Ok(())
-        } else {
-            Err(imp::cleanup(payload))
-        }
-    })
-}
-
-/// Determines whether the current thread is unwinding because of panic.
-pub fn panicking() -> bool {
-    PANIC_COUNT.with(|s| s.get() != 0)
-}
-
-// An uninlined, unmangled function upon which to slap yer breakpoints
-#[inline(never)]
-#[no_mangle]
-#[allow(private_no_mangle_fns)]
-pub fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
-    unsafe {
-        imp::panic(cause)
-    }
-}
-
-#[cfg(not(test))]
-/// Entry point of panic from the libcore crate.
-#[lang = "panic_fmt"]
-#[unwind]
-pub extern fn rust_begin_unwind(msg: fmt::Arguments,
-                                file: &'static str, line: u32) -> ! {
-    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 `panic!()` has as low an impact
-/// on (e.g.) the inlining of other functions as possible), by moving
-/// the actual formatting into this shared place.
-#[unstable(feature = "libstd_sys_internals",
-           reason = "used by the panic! macro",
-           issue = "0")]
-#[inline(never)] #[cold]
-pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
-    use fmt::Write;
-
-    // We do two allocations here, unfortunately. But (a) they're
-    // required with the current scheme, and (b) we don't handle
-    // panic + OOM properly anyway (see comment in begin_unwind
-    // below).
-
-    let mut s = String::new();
-    let _ = s.write_fmt(msg);
-    begin_unwind_inner(Box::new(s), file_line)
-}
-
-/// This is the entry point of unwinding for panic!() and assert!().
-#[unstable(feature = "libstd_sys_internals",
-           reason = "used by the panic! macro",
-           issue = "0")]
-#[inline(never)] #[cold] // avoid code bloat at the call sites as much as possible
-pub fn begin_unwind<M: Any + Send>(msg: M, file_line: &(&'static str, u32)) -> ! {
-    // Note that this should be the only allocation performed in this code path.
-    // Currently this means that panic!() on OOM will invoke this code path,
-    // but then again we're not really ready for panic on OOM anyway. If
-    // we do start doing this, then we should propagate this allocation to
-    // be performed in the parent of this thread instead of the thread that's
-    // panicking.
-
-    // see below for why we do the `Any` coercion here.
-    begin_unwind_inner(Box::new(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 noticeably slower). (Note:
-/// we need the `Any` object anyway, we're not just creating it to
-/// avoid being generic.)
-///
-/// Doing this split took the LLVM IR line counts of `fn main() { panic!()
-/// }` 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_line: &(&'static str, u32)) -> ! {
-    let (file, line) = *file_line;
-
-    // First, invoke the default panic handler.
-    panicking::on_panic(&*msg, file, line);
-
-    // Finally, perform the unwinding.
-    rust_panic(msg);
-}
diff --git a/src/libstd/sys/common/unwind/seh.rs b/src/libstd/sys/common/unwind/seh.rs
deleted file mode 100644
index 94da42f0092..00000000000
--- a/src/libstd/sys/common/unwind/seh.rs
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2015 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.
-
-//! Windows SEH
-//!
-//! On Windows (currently only on MSVC), the default exception handling
-//! mechanism is Structured Exception Handling (SEH). This is quite different
-//! than Dwarf-based exception handling (e.g. what other unix platforms use) in
-//! terms of compiler internals, so LLVM is required to have a good deal of
-//! extra support for SEH.
-//!
-//! In a nutshell, what happens here is:
-//!
-//! 1. The `panic` function calls the standard Windows function `RaiseException`
-//!    with a Rust-specific code, triggering the unwinding process.
-//! 2. All landing pads generated by the compiler use the personality function
-//!    `__C_specific_handler` on 64-bit and `__except_handler3` on 32-bit,
-//!    functions in the CRT, and the unwinding code in Windows will use this
-//!    personality function to execute all cleanup code on the stack.
-//! 3. All compiler-generated calls to `invoke` have a landing pad set as a
-//!    `cleanuppad` LLVM instruction, which indicates the start of the cleanup
-//!    routine. The personality (in step 2, defined in the CRT) is responsible
-//!    for running the cleanup routines.
-//! 4. Eventually the "catch" code in the `try` intrinsic (generated by the
-//!    compiler) is executed, which will ensure that the exception being caught
-//!    is indeed a Rust exception, indicating that control should come back to
-//!    Rust. This is done via a `catchswitch` plus a `catchpad` instruction in
-//!    LLVM IR terms, finally returning normal control to the program with a
-//!    `catchret` instruction. The `try` intrinsic uses a filter function to
-//!    detect what kind of exception is being thrown, and this detection is
-//!    implemented as the msvc_try_filter language item below.
-//!
-//! Some specific differences from the gcc-based exception handling are:
-//!
-//! * Rust has no custom personality function, it is instead *always*
-//!   __C_specific_handler or __except_handler3, so the filtering is done in a
-//!   C++-like manner instead of in the personality function itself. Note that
-//!   the precise codegen for this was lifted from an LLVM test case for SEH
-//!   (this is the `__rust_try_filter` function below).
-//! * We've got some data to transmit across the unwinding boundary,
-//!   specifically a `Box<Any + Send + 'static>`. Like with Dwarf exceptions
-//!   these two pointers are stored as a payload in the exception itself. On
-//!   MSVC, however, there's no need for an extra allocation because the call
-//!   stack is preserved while filter functions are being executed. This means
-//!   that the pointers are passed directly to `RaiseException` which are then
-//!   recovered in the filter function to be written to the stack frame of the
-//!   `try` intrinsic.
-//!
-//! [win64]: http://msdn.microsoft.com/en-us/library/1eyas8tf.aspx
-//! [llvm]: http://llvm.org/docs/ExceptionHandling.html#background-on-windows-exceptions
-
-use sys::c;
-
-// A code which indicates panics that originate from Rust. Note that some of the
-// upper bits are used by the system so we just set them to 0 and ignore them.
-//                           0x 0 R S T
-const RUST_PANIC: c::DWORD = 0x00525354;
-
-pub use self::imp::*;
-
-mod imp {
-    use prelude::v1::*;
-
-    use any::Any;
-    use mem;
-    use raw;
-    use super::RUST_PANIC;
-    use sys::c;
-
-    pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
-        // As mentioned above, the call stack here is preserved while the filter
-        // functions are running, so it's ok to pass stack-local arrays into
-        // `RaiseException`.
-        //
-        // The two pointers of the `data` trait object are written to the stack,
-        // passed to `RaiseException`, and they're later extracted by the filter
-        // function below in the "custom exception information" section of the
-        // `EXCEPTION_RECORD` type.
-        let ptrs = mem::transmute::<_, raw::TraitObject>(data);
-        let ptrs = [ptrs.data, ptrs.vtable];
-        c::RaiseException(RUST_PANIC, 0, 2, ptrs.as_ptr() as *mut _);
-        rtabort!("could not unwind stack");
-    }
-
-    pub fn payload() -> [usize; 2] {
-        [0; 2]
-    }
-
-    pub unsafe fn cleanup(payload: [usize; 2]) -> Box<Any + Send + 'static> {
-        mem::transmute(raw::TraitObject {
-            data: payload[0] as *mut _,
-            vtable: payload[1] as *mut _,
-        })
-    }
-
-    // This is quite a special function, and it's not literally passed in as the
-    // filter function for the `catchpad` of the `try` intrinsic. The compiler
-    // actually generates its own filter function wrapper which will delegate to
-    // this for the actual execution logic for whether the exception should be
-    // caught. The reasons for this are:
-    //
-    // * Each architecture has a slightly different ABI for the filter function
-    //   here. For example on x86 there are no arguments but on x86_64 there are
-    //   two.
-    // * This function needs access to the stack frame of the `try` intrinsic
-    //   which is using this filter as a catch pad. This is because the payload
-    //   of this exception, `Box<Any>`, needs to be transmitted to that
-    //   location.
-    //
-    // Both of these differences end up using a ton of weird llvm-specific
-    // intrinsics, so it's actually pretty difficult to express the entire
-    // filter function in Rust itself. As a compromise, the compiler takes care
-    // of all the weird LLVM-specific and platform-specific stuff, getting to
-    // the point where this function makes the actual decision about what to
-    // catch given two parameters.
-    //
-    // The first parameter is `*mut EXCEPTION_POINTERS` which is some contextual
-    // information about the exception being filtered, and the second pointer is
-    // `*mut *mut [usize; 2]` (the payload here). This value points directly
-    // into the stack frame of the `try` intrinsic itself, and we use it to copy
-    // information from the exception onto the stack.
-    #[lang = "msvc_try_filter"]
-    #[cfg(not(test))]
-    unsafe extern fn __rust_try_filter(eh_ptrs: *mut u8,
-                                       payload: *mut u8) -> i32 {
-        let eh_ptrs = eh_ptrs as *mut c::EXCEPTION_POINTERS;
-        let payload = payload as *mut *mut [usize; 2];
-        let record = &*(*eh_ptrs).ExceptionRecord;
-        if record.ExceptionCode != RUST_PANIC {
-            return 0
-        }
-        (**payload)[0] = record.ExceptionInformation[0] as usize;
-        (**payload)[1] = record.ExceptionInformation[1] as usize;
-        return 1
-    }
-}
-
-// This is required by the compiler to exist (e.g. it's a lang item), but
-// it's never actually called by the compiler because __C_specific_handler
-// or _except_handler3 is the personality function that is always used.
-// Hence this is just an aborting stub.
-#[lang = "eh_personality"]
-#[cfg(not(test))]
-fn rust_eh_personality() {
-    unsafe { ::intrinsics::abort() }
-}
diff --git a/src/libstd/sys/common/unwind/seh64_gnu.rs b/src/libstd/sys/common/unwind/seh64_gnu.rs
deleted file mode 100644
index 57281d67ebb..00000000000
--- a/src/libstd/sys/common/unwind/seh64_gnu.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2015 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.
-
-//! Unwinding implementation of top of native Win64 SEH,
-//! however the unwind handler data (aka LSDA) uses GCC-compatible encoding.
-
-#![allow(bad_style)]
-#![allow(private_no_mangle_fns)]
-
-use prelude::v1::*;
-
-use any::Any;
-use sys_common::dwarf::eh;
-use core::mem;
-use core::ptr;
-use sys::c;
-
-// Define our exception codes:
-// according to http://msdn.microsoft.com/en-us/library/het71c37(v=VS.80).aspx,
-//    [31:30] = 3 (error), 2 (warning), 1 (info), 0 (success)
-//    [29]    = 1 (user-defined)
-//    [28]    = 0 (reserved)
-// we define bits:
-//    [24:27] = type
-//    [0:23]  = magic
-const ETYPE: c::DWORD = 0b1110_u32 << 28;
-const MAGIC: c::DWORD = 0x525354; // "RST"
-
-const RUST_PANIC: c::DWORD  = ETYPE | (1 << 24) | MAGIC;
-
-#[repr(C)]
-struct PanicData {
-    data: Box<Any + Send + 'static>
-}
-
-pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
-    let panic_ctx = Box::new(PanicData { data: data });
-    let params = [Box::into_raw(panic_ctx) as c::ULONG_PTR];
-    c::RaiseException(RUST_PANIC,
-                      c::EXCEPTION_NONCONTINUABLE,
-                      params.len() as c::DWORD,
-                      &params as *const c::ULONG_PTR);
-    rtabort!("could not unwind stack");
-}
-
-pub fn payload() -> *mut u8 {
-    0 as *mut u8
-}
-
-pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
-    let panic_ctx = Box::from_raw(ptr as *mut PanicData);
-    return panic_ctx.data;
-}
-
-// SEH doesn't support resuming unwinds after calling a landing pad like
-// libunwind does. For this reason, MSVC compiler outlines landing pads into
-// separate functions that can be called directly from the personality function
-// but are nevertheless able to find and modify stack frame of the "parent"
-// function.
-//
-// Since this cannot be done with libdwarf-style landing pads,
-// rust_eh_personality instead catches RUST_PANICs, runs the landing pad, then
-// reraises the exception.
-//
-// Note that it makes certain assumptions about the exception:
-//
-// 1. That RUST_PANIC is non-continuable, so no lower stack frame may choose to
-//    resume execution.
-// 2. That the first parameter of the exception is a pointer to an extra data
-//    area (PanicData).
-// Since these assumptions do not generally hold true for foreign exceptions
-// (system faults, C++ exceptions, etc), we make no attempt to invoke our
-// landing pads (and, thus, destructors!) for anything other than RUST_PANICs.
-// This is considered acceptable, because the behavior of throwing exceptions
-// through a C ABI boundary is undefined.
-
-#[lang = "eh_personality_catch"]
-#[cfg(not(test))]
-unsafe extern fn rust_eh_personality_catch(
-    exceptionRecord: *mut c::EXCEPTION_RECORD,
-    establisherFrame: c::LPVOID,
-    contextRecord: *mut c::CONTEXT,
-    dispatcherContext: *mut c::DISPATCHER_CONTEXT
-) -> c::EXCEPTION_DISPOSITION
-{
-    rust_eh_personality(exceptionRecord, establisherFrame,
-                        contextRecord, dispatcherContext)
-}
-
-#[lang = "eh_personality"]
-#[cfg(not(test))]
-unsafe extern fn rust_eh_personality(
-    exceptionRecord: *mut c::EXCEPTION_RECORD,
-    establisherFrame: c::LPVOID,
-    contextRecord: *mut c::CONTEXT,
-    dispatcherContext: *mut c::DISPATCHER_CONTEXT
-) -> c::EXCEPTION_DISPOSITION
-{
-    let er = &*exceptionRecord;
-    let dc = &*dispatcherContext;
-
-    if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 { // we are in the dispatch phase
-        if er.ExceptionCode == RUST_PANIC {
-            if let Some(lpad) = find_landing_pad(dc) {
-                c::RtlUnwindEx(establisherFrame,
-                               lpad as c::LPVOID,
-                               exceptionRecord,
-                               er.ExceptionInformation[0] as c::LPVOID, // pointer to PanicData
-                               contextRecord,
-                               dc.HistoryTable);
-                rtabort!("could not unwind");
-            }
-        }
-    }
-    c::ExceptionContinueSearch
-}
-
-#[cfg(not(test))]
-#[lang = "eh_unwind_resume"]
-#[unwind]
-unsafe extern fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
-    let params = [panic_ctx as c::ULONG_PTR];
-    c::RaiseException(RUST_PANIC,
-                      c::EXCEPTION_NONCONTINUABLE,
-                      params.len() as c::DWORD,
-                      &params as *const c::ULONG_PTR);
-    rtabort!("could not resume unwind");
-}
-
-unsafe fn find_landing_pad(dc: &c::DISPATCHER_CONTEXT) -> Option<usize> {
-    let eh_ctx = eh::EHContext {
-        ip: dc.ControlPc as usize,
-        func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
-        text_start: dc.ImageBase as usize,
-        data_start: 0
-    };
-    eh::find_landing_pad(dc.HandlerData, &eh_ctx)
-}
diff --git a/src/libstd/sys/common/util.rs b/src/libstd/sys/common/util.rs
index b7a6b7650d5..b5d03576338 100644
--- a/src/libstd/sys/common/util.rs
+++ b/src/libstd/sys/common/util.rs
@@ -10,7 +10,6 @@
 
 use env;
 use fmt;
-use intrinsics;
 use io::prelude::*;
 use sync::atomic::{self, Ordering};
 use sys::stdio::Stderr;
@@ -34,9 +33,40 @@ pub fn dumb_print(args: fmt::Arguments) {
     let _ = Stderr::new().map(|mut stderr| stderr.write_fmt(args));
 }
 
+// On Unix-like platforms, libc::abort will unregister signal handlers
+// including the SIGABRT handler, preventing the abort from being blocked, and
+// fclose streams, with the side effect of flushing them so libc bufferred
+// output will be printed.  Additionally the shell will generally print a more
+// understandable error message like "Abort trap" rather than "Illegal
+// instruction" that intrinsics::abort would cause, as intrinsics::abort is
+// implemented as an illegal instruction.
+#[cfg(unix)]
+unsafe fn abort_internal() -> ! {
+    ::libc::abort()
+}
+
+// On Windows, use the processor-specific __fastfail mechanism.  In Windows 8
+// and later, this will terminate the process immediately without running any
+// in-process exception handlers.  In earlier versions of Windows, this
+// sequence of instructions will be treated as an access violation,
+// terminating the process but without necessarily bypassing all exception
+// handlers.
+//
+// https://msdn.microsoft.com/en-us/library/dn774154.aspx
+#[cfg(all(windows, any(target_arch = "x86", target_arch = "x86_64")))]
+unsafe fn abort_internal() -> ! {
+    asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT
+    ::intrinsics::unreachable();
+}
+
+// Other platforms should use the appropriate platform-specific mechanism for
+// aborting the process.  If no platform-specific mechanism is available,
+// ::intrinsics::abort() may be used instead.  The above implementations cover
+// all targets currently supported by libstd.
+
 pub fn abort(args: fmt::Arguments) -> ! {
     dumb_print(format_args!("fatal runtime error: {}\n", args));
-    unsafe { intrinsics::abort(); }
+    unsafe { abort_internal(); }
 }
 
 #[allow(dead_code)] // stack overflow detection not enabled on all platforms
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index 55e485e5811..2c1a656290f 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -567,7 +567,7 @@ impl Wtf8 {
             return None
         }
         match &self.bytes[(len - 3)..] {
-            [0xED, b2 @ 0xA0...0xAF, b3] => Some(decode_surrogate(b2, b3)),
+            &[0xED, b2 @ 0xA0...0xAF, b3] => Some(decode_surrogate(b2, b3)),
             _ => None
         }
     }
@@ -579,7 +579,7 @@ impl Wtf8 {
             return None
         }
         match &self.bytes[..3] {
-            [0xED, b2 @ 0xB0...0xBF, b3] => Some(decode_surrogate(b2, b3)),
+            &[0xED, b2 @ 0xB0...0xBF, b3] => Some(decode_surrogate(b2, b3)),
             _ => None
         }
     }
@@ -715,7 +715,7 @@ impl<'a> Iterator for Wtf8CodePoints<'a> {
 
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let (len, _) = self.bytes.size_hint();
+        let len = self.bytes.len();
         (len.saturating_add(3) / 4, Some(len))
     }
 }
diff --git a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
index de93d3d4e50..ca2e70b5003 100644
--- a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
@@ -18,12 +18,11 @@
 /// simple to use it should be used only on iOS devices as the only viable
 /// option.
 
-use io;
 use io::prelude::*;
+use io;
 use libc;
 use mem;
-use result::Result::Ok;
-use sync::StaticMutex;
+use sys::mutex::Mutex;
 
 use super::super::printing::print;
 
@@ -37,18 +36,21 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // while it doesn't requires lock for work as everything is
     // local, it still displays much nicer backtraces when a
     // couple of threads panic simultaneously
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
 
-    writeln!(w, "stack backtrace:")?;
-    // 100 lines should be enough
-    const SIZE: usize = 100;
-    let mut buf: [*mut libc::c_void; SIZE] = unsafe { mem::zeroed() };
-    let cnt = unsafe { backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize};
+        writeln!(w, "stack backtrace:")?;
+        // 100 lines should be enough
+        const SIZE: usize = 100;
+        let mut buf: [*mut libc::c_void; SIZE] = mem::zeroed();
+        let cnt = backtrace(buf.as_mut_ptr(), SIZE as libc::c_int) as usize;
 
-    // skipping the first one as it is write itself
-    for i in 1..cnt {
-        print(w, i as isize, buf[i], buf[i])?
+        // skipping the first one as it is write itself
+        for i in 1..cnt {
+            print(w, i as isize, buf[i], buf[i])?
+        }
+        LOCK.unlock();
     }
     Ok(())
 }
diff --git a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
index 8d880917166..c1b45620ab0 100644
--- a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
@@ -12,9 +12,10 @@ use io;
 use io::prelude::*;
 use libc;
 use mem;
-use sync::StaticMutex;
+use sys_common::mutex::Mutex;
 
 use super::super::printing::print;
+use unwind as uw;
 
 #[inline(never)] // if we know this is a function call, we can skip it when
                  // tracing
@@ -30,24 +31,28 @@ pub fn write(w: &mut Write) -> io::Result<()> {
     // is semi-reasonable in terms of printing anyway, and we know that all
     // I/O done here is blocking I/O, not green I/O, so we don't have to
     // worry about this being a native vs green mutex.
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
-
-    writeln!(w, "stack backtrace:")?;
-
-    let mut cx = Context { writer: w, last_error: None, idx: 0 };
-    return match unsafe {
-        uw::_Unwind_Backtrace(trace_fn,
-                              &mut cx as *mut Context as *mut libc::c_void)
-    } {
-        uw::_URC_NO_REASON => {
-            match cx.last_error {
-                Some(err) => Err(err),
-                None => Ok(())
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
+
+        writeln!(w, "stack backtrace:")?;
+
+        let mut cx = Context { writer: w, last_error: None, idx: 0 };
+        let ret = match {
+            uw::_Unwind_Backtrace(trace_fn,
+                                  &mut cx as *mut Context as *mut libc::c_void)
+        } {
+            uw::_URC_NO_REASON => {
+                match cx.last_error {
+                    Some(err) => Err(err),
+                    None => Ok(())
+                }
             }
-        }
-        _ => Ok(()),
-    };
+            _ => Ok(()),
+        };
+        LOCK.unlock();
+        return ret
+    }
 
     extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
                        arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
@@ -102,126 +107,3 @@ pub fn write(w: &mut Write) -> io::Result<()> {
         uw::_URC_NO_REASON
     }
 }
-
-/// Unwind library interface used for backtraces
-///
-/// Note that dead code is allowed as here are just bindings
-/// iOS doesn't use all of them it but adding more
-/// platform-specific configs pollutes the code too much
-#[allow(non_camel_case_types)]
-#[allow(non_snake_case)]
-mod uw {
-    pub use self::_Unwind_Reason_Code::*;
-
-    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: *mut _Unwind_Context,
-                      arg: *mut libc::c_void) -> _Unwind_Reason_Code;
-
-    extern {
-        // No native _Unwind_Backtrace on iOS
-        #[cfg(not(all(target_os = "ios", target_arch = "arm")))]
-        pub fn _Unwind_Backtrace(trace: _Unwind_Trace_Fn,
-                                 trace_argument: *mut libc::c_void)
-                    -> _Unwind_Reason_Code;
-
-        // available since GCC 4.2.0, should be fine for our purpose
-        #[cfg(all(not(all(target_os = "android", target_arch = "arm")),
-                  not(all(target_os = "linux", target_arch = "arm"))))]
-        pub fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
-                                 ip_before_insn: *mut libc::c_int)
-                    -> libc::uintptr_t;
-
-        #[cfg(all(not(target_os = "android"),
-                  not(all(target_os = "linux", target_arch = "arm"))))]
-        pub fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void)
-            -> *mut 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(any(all(target_os = "android", target_arch = "arm"),
-              all(target_os = "linux", target_arch = "arm")))]
-    pub unsafe fn _Unwind_GetIP(ctx: *mut _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: *mut _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, _Unwind_VRS_RegClass::_UVRSC_CORE, 15,
-                                _Unwind_VRS_DataRepresentation::_UVRSD_UINT32,
-                                ptr as *mut libc::c_void);
-        (val & !1) as libc::uintptr_t
-    }
-
-    // This function doesn't exist on Android or ARM/Linux, so make it same
-    // to _Unwind_GetIP
-    #[cfg(any(all(target_os = "android", target_arch = "arm"),
-              all(target_os = "linux", target_arch = "arm")))]
-    pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
-                                    ip_before_insn: *mut libc::c_int)
-        -> libc::uintptr_t
-    {
-        *ip_before_insn = 0;
-        _Unwind_GetIP(ctx)
-    }
-
-    // This function also doesn't exist on Android or ARM/Linux, so make it
-    // a no-op
-    #[cfg(any(target_os = "android",
-              all(target_os = "linux", target_arch = "arm")))]
-    pub unsafe fn _Unwind_FindEnclosingFunction(pc: *mut libc::c_void)
-        -> *mut libc::c_void
-    {
-        pc
-    }
-}
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index a1528458860..54340773a42 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -88,9 +88,7 @@ pub trait OpenOptionsExt {
     /// }
     /// let file = options.open("foo.txt");
     /// ```
-    #[unstable(feature = "expand_open_options",
-               reason = "recently added",
-               issue = "30014")]
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn custom_flags(&mut self, flags: i32) -> &mut Self;
 }
 
@@ -198,6 +196,22 @@ impl FileTypeExt for fs::FileType {
 pub trait DirEntryExt {
     /// Returns the underlying `d_ino` field in the contained `dirent`
     /// structure.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    /// use std::os::unix::fs::DirEntryExt;
+    ///
+    /// if let Ok(entries) = fs::read_dir(".") {
+    ///     for entry in entries {
+    ///         if let Ok(entry) = entry {
+    ///             // Here, `entry` is a `DirEntry`.
+    ///             println!("{:?}: {}", entry.file_name(), entry.ino());
+    ///         }
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "dir_entry_ext", since = "1.1.0")]
     fn ino(&self) -> u64;
 }
@@ -241,6 +255,16 @@ pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
 pub trait DirBuilderExt {
     /// Sets the mode to create new directories with. This option defaults to
     /// 0o777.
+    ///
+    /// # Examples
+    ///
+    /// ```ignore
+    /// use std::fs::DirBuilder;
+    /// use std::os::unix::fs::DirBuilderExt;
+    ///
+    /// let mut builder = DirBuilder::new();
+    /// builder.mode(0o755);
+    /// ```
     #[stable(feature = "dir_builder", since = "1.6.0")]
     fn mode(&mut self, mode: u32) -> &mut Self;
 }
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index a74f7ea13b4..b5287cce484 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -7,7 +7,8 @@
 // <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.
-#![unstable(feature = "unix_socket", reason = "newly added", issue = "32312")]
+
+#![stable(feature = "unix_socket", since = "1.10.0")]
 
 //! Unix-specific networking functionality
 
@@ -75,6 +76,7 @@ enum AddressKind<'a> {
 
 /// An address associated with a Unix socket.
 #[derive(Clone)]
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct SocketAddr {
     addr: libc::sockaddr_un,
     len: libc::socklen_t,
@@ -109,6 +111,7 @@ impl SocketAddr {
     }
 
     /// Returns true iff the address is unnamed.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn is_unnamed(&self) -> bool {
         if let AddressKind::Unnamed = self.address() {
             true
@@ -118,6 +121,7 @@ impl SocketAddr {
     }
 
     /// Returns the contents of this address if it is a `pathname` address.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn as_pathname(&self) -> Option<&Path> {
         if let AddressKind::Pathname(path) = self.address() {
             Some(path)
@@ -141,6 +145,7 @@ impl SocketAddr {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for SocketAddr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match self.address() {
@@ -168,8 +173,6 @@ impl<'a> fmt::Display for AsciiEscaped<'a> {
 /// # Examples
 ///
 /// ```rust,no_run
-/// #![feature(unix_socket)]
-///
 /// use std::os::unix::net::UnixStream;
 /// use std::io::prelude::*;
 ///
@@ -179,8 +182,10 @@ impl<'a> fmt::Display for AsciiEscaped<'a> {
 /// stream.read_to_string(&mut response).unwrap();
 /// println!("{}", response);
 /// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixStream(Socket);
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for UnixStream {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixStream");
@@ -197,6 +202,7 @@ impl fmt::Debug for UnixStream {
 
 impl UnixStream {
     /// Connects to the socket named by `path`.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
         fn inner(path: &Path) -> io::Result<UnixStream> {
             unsafe {
@@ -213,6 +219,7 @@ impl UnixStream {
     /// Creates an unnamed pair of connected sockets.
     ///
     /// Returns two `UnixStream`s which are connected to each other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
         Ok((UnixStream(i1), UnixStream(i2)))
@@ -224,16 +231,19 @@ impl UnixStream {
     /// object references. Both handles will read and write the same stream of
     /// data, and options set on one stream will be propogated to the other
     /// stream.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixStream> {
         self.0.duplicate().map(UnixStream)
     }
 
     /// Returns the socket address of the local half of this connection.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
 
     /// Returns the socket address of the remote half of this connection.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
     }
@@ -243,6 +253,7 @@ impl UnixStream {
     /// If the provided value is `None`, then `read` calls will block
     /// indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
     }
@@ -252,26 +263,31 @@ impl UnixStream {
     /// If the provided value is `None`, then `write` calls will block
     /// indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
     }
 
     /// Returns the read timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_RCVTIMEO)
     }
 
     /// Returns the write timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_SNDTIMEO)
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
     }
@@ -281,11 +297,13 @@ impl UnixStream {
     /// This function will cause all pending and future I/O calls on the
     /// specified portions to immediately return with an appropriate value
     /// (see the documentation of `Shutdown`).
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl io::Read for UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         io::Read::read(&mut &*self, buf)
@@ -296,6 +314,7 @@ impl io::Read for UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> io::Read for &'a UnixStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
@@ -306,6 +325,7 @@ impl<'a> io::Read for &'a UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl io::Write for UnixStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         io::Write::write(&mut &*self, buf)
@@ -316,6 +336,7 @@ impl io::Write for UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> io::Write for &'a UnixStream {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
@@ -326,18 +347,21 @@ impl<'a> io::Write for &'a UnixStream {
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl AsRawFd for UnixStream {
     fn as_raw_fd(&self) -> RawFd {
         *self.0.as_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl FromRawFd for UnixStream {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
         UnixStream(Socket::from_inner(fd))
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl IntoRawFd for UnixStream {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_inner()
@@ -349,8 +373,6 @@ impl IntoRawFd for UnixStream {
 /// # Examples
 ///
 /// ```rust,no_run
-/// #![feature(unix_socket)]
-///
 /// use std::thread;
 /// use std::os::unix::net::{UnixStream, UnixListener};
 ///
@@ -377,8 +399,10 @@ impl IntoRawFd for UnixStream {
 /// // close the listener socket
 /// drop(listener);
 /// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixListener(Socket);
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for UnixListener {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixListener");
@@ -392,6 +416,7 @@ impl fmt::Debug for UnixListener {
 
 impl UnixListener {
     /// Creates a new `UnixListener` bound to the specified socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
         fn inner(path: &Path) -> io::Result<UnixListener> {
             unsafe {
@@ -412,6 +437,7 @@ impl UnixListener {
     /// This function will block the calling thread until a new Unix connection
     /// is established. When established, the corersponding `UnixStream` and
     /// the remote peer's address will be returned.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
         let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
         let mut len = mem::size_of_val(&storage) as libc::socklen_t;
@@ -425,21 +451,25 @@ impl UnixListener {
     /// The returned `UnixListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixListener> {
         self.0.duplicate().map(UnixListener)
     }
 
     /// Returns the local socket address of this listener.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
     }
@@ -448,29 +478,34 @@ impl UnixListener {
     ///
     /// The iterator will never return `None` and will also not yield the
     /// peer's `SocketAddr` structure.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn incoming<'a>(&'a self) -> Incoming<'a> {
         Incoming { listener: self }
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl AsRawFd for UnixListener {
     fn as_raw_fd(&self) -> RawFd {
         *self.0.as_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl FromRawFd for UnixListener {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
         UnixListener(Socket::from_inner(fd))
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl IntoRawFd for UnixListener {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> IntoIterator for &'a UnixListener {
     type Item = io::Result<UnixStream>;
     type IntoIter = Incoming<'a>;
@@ -484,10 +519,12 @@ impl<'a> IntoIterator for &'a UnixListener {
 ///
 /// It will never return `None`.
 #[derive(Debug)]
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct Incoming<'a> {
     listener: &'a UnixListener,
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl<'a> Iterator for Incoming<'a> {
     type Item = io::Result<UnixStream>;
 
@@ -505,8 +542,6 @@ impl<'a> Iterator for Incoming<'a> {
 /// # Examples
 ///
 /// ```rust,no_run
-/// #![feature(unix_socket)]
-///
 /// use std::os::unix::net::UnixDatagram;
 ///
 /// let socket = UnixDatagram::bind("/path/to/my/socket").unwrap();
@@ -515,8 +550,10 @@ impl<'a> Iterator for Incoming<'a> {
 /// let (count, address) = socket.recv_from(&mut buf).unwrap();
 /// println!("socket {:?} sent {:?}", address, &buf[..count]);
 /// ```
+#[stable(feature = "unix_socket", since = "1.10.0")]
 pub struct UnixDatagram(Socket);
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl fmt::Debug for UnixDatagram {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let mut builder = fmt.debug_struct("UnixDatagram");
@@ -533,6 +570,7 @@ impl fmt::Debug for UnixDatagram {
 
 impl UnixDatagram {
     /// Creates a Unix datagram socket bound to the given path.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixDatagram> {
         fn inner(path: &Path) -> io::Result<UnixDatagram> {
             unsafe {
@@ -548,6 +586,7 @@ impl UnixDatagram {
     }
 
     /// Creates a Unix Datagram socket which is not bound to any address.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn unbound() -> io::Result<UnixDatagram> {
         let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_DGRAM)?;
         Ok(UnixDatagram(inner))
@@ -556,6 +595,7 @@ impl UnixDatagram {
     /// Create an unnamed pair of connected sockets.
     ///
     /// Returns two `UnixDatagrams`s which are connected to each other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn pair() -> io::Result<(UnixDatagram, UnixDatagram)> {
         let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_DGRAM)?;
         Ok((UnixDatagram(i1), UnixDatagram(i2)))
@@ -565,6 +605,7 @@ impl UnixDatagram {
     ///
     /// The `send` method may be used to send data to the specified address.
     /// `recv` and `recv_from` will only receive data from that address.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn connect<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
         fn inner(d: &UnixDatagram, path: &Path) -> io::Result<()> {
             unsafe {
@@ -583,11 +624,13 @@ impl UnixDatagram {
     /// The returned `UnixListener` is a reference to the same socket that this
     /// object references. Both handles can be used to accept incoming
     /// connections and options set on one listener will affect the other.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn try_clone(&self) -> io::Result<UnixDatagram> {
         self.0.duplicate().map(UnixDatagram)
     }
 
     /// Returns the address of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn local_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getsockname(*self.0.as_inner(), addr, len) })
     }
@@ -595,6 +638,7 @@ impl UnixDatagram {
     /// Returns the address of this socket's peer.
     ///
     /// The `connect` method will connect the socket to a peer.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
         SocketAddr::new(|addr, len| unsafe { libc::getpeername(*self.0.as_inner(), addr, len) })
     }
@@ -603,6 +647,7 @@ impl UnixDatagram {
     ///
     /// On success, returns the number of bytes read and the address from
     /// whence the data came.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
         let mut count = 0;
         let addr = SocketAddr::new(|addr, len| {
@@ -629,6 +674,7 @@ impl UnixDatagram {
     /// Receives data from the socket.
     ///
     /// On success, returns the number of bytes read.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.read(buf)
     }
@@ -636,6 +682,7 @@ impl UnixDatagram {
     /// Sends data on the socket to the specified address.
     ///
     /// On success, returns the number of bytes written.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn send_to<P: AsRef<Path>>(&self, buf: &[u8], path: P) -> io::Result<usize> {
         fn inner(d: &UnixDatagram, buf: &[u8], path: &Path) -> io::Result<usize> {
             unsafe {
@@ -659,6 +706,7 @@ impl UnixDatagram {
     /// will return an error if the socket has not already been connected.
     ///
     /// On success, returns the number of bytes written.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
         self.0.write(buf)
     }
@@ -668,6 +716,7 @@ impl UnixDatagram {
     /// If the provided value is `None`, then `recv` and `recv_from` calls will
     /// block indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
     }
@@ -677,26 +726,31 @@ impl UnixDatagram {
     /// If the provided value is `None`, then `send` and `send_to` calls will
     /// block indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
         self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
     }
 
     /// Returns the read timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_RCVTIMEO)
     }
 
     /// Returns the write timeout of this socket.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
         self.0.timeout(libc::SO_SNDTIMEO)
     }
 
     /// Moves the socket into or out of nonblocking mode.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         self.0.set_nonblocking(nonblocking)
     }
 
     /// Returns the value of the `SO_ERROR` option.
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
         self.0.take_error()
     }
@@ -706,23 +760,27 @@ impl UnixDatagram {
     /// This function will cause all pending and future I/O calls on the
     /// specified portions to immediately return with an appropriate value
     /// (see the documentation of `Shutdown`).
+    #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         self.0.shutdown(how)
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl AsRawFd for UnixDatagram {
     fn as_raw_fd(&self) -> RawFd {
         *self.0.as_inner()
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl FromRawFd for UnixDatagram {
     unsafe fn from_raw_fd(fd: RawFd) -> UnixDatagram {
         UnixDatagram(Socket::from_inner(fd))
     }
 }
 
+#[stable(feature = "unix_socket", since = "1.10.0")]
 impl IntoRawFd for UnixDatagram {
     fn into_raw_fd(self) -> RawFd {
         self.0.into_inner()
diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs
index 7f31cf9f3bf..430ec5f94a6 100644
--- a/src/libstd/sys/unix/ext/process.rs
+++ b/src/libstd/sys/unix/ext/process.rs
@@ -34,21 +34,6 @@ pub trait CommandExt {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn gid(&mut self, id: u32) -> &mut process::Command;
 
-    /// Create a new session (cf. `setsid(2)`) for the child process. This means
-    /// that the child is the leader of a new process group. The parent process
-    /// remains the child reaper of the new process.
-    ///
-    /// This is not enough to create a daemon process. The *init* process should
-    /// be the child reaper of a daemon. This can be achieved if the parent
-    /// process exit. Moreover, a daemon should not have a controlling terminal.
-    /// To achieve this, a session leader (the child) must spawn another process
-    /// (the daemon) in the same session.
-    #[unstable(feature = "process_session_leader", reason = "recently added",
-               issue = "27811")]
-    #[rustc_deprecated(reason = "use `before_exec` instead",
-                       since = "1.9.0")]
-    fn session_leader(&mut self, on: bool) -> &mut process::Command;
-
     /// Schedules a closure to be run just before the `exec` function is
     /// invoked.
     ///
@@ -112,11 +97,6 @@ impl CommandExt for process::Command {
         self
     }
 
-    fn session_leader(&mut self, on: bool) -> &mut process::Command {
-        self.as_inner_mut().session_leader(on);
-        self
-    }
-
     fn before_exec<F>(&mut self, f: F) -> &mut process::Command
         where F: FnMut() -> io::Result<()> + Send + Sync + 'static
     {
@@ -132,6 +112,11 @@ impl CommandExt for process::Command {
 /// Unix-specific extensions to `std::process::ExitStatus`
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait ExitStatusExt {
+    /// Creates a new `ExitStatus` from the raw underlying `i32` return value of
+    /// a process.
+    #[unstable(feature = "exit_status_from", issue = "32713")]
+    fn from_raw(raw: i32) -> Self;
+
     /// If the process was terminated by a signal, returns that signal.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn signal(&self) -> Option<i32>;
@@ -139,6 +124,10 @@ pub trait ExitStatusExt {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ExitStatusExt for process::ExitStatus {
+    fn from_raw(raw: i32) -> Self {
+        process::ExitStatus::from_inner(From::from(raw))
+    }
+
     fn signal(&self) -> Option<i32> {
         self.as_inner().signal()
     }
diff --git a/src/libstd/sys/unix/ext/raw.rs b/src/libstd/sys/unix/ext/raw.rs
index 96535e88604..7972990e67d 100644
--- a/src/libstd/sys/unix/ext/raw.rs
+++ b/src/libstd/sys/unix/ext/raw.rs
@@ -23,7 +23,7 @@
 #[stable(feature = "raw_ext", since = "1.1.0")] pub type pid_t = i32;
 
 #[doc(inline)]
-#[unstable(feature = "pthread_t", issue = "29791")]
+#[stable(feature = "pthread_t", since = "1.8.0")]
 pub use sys::platform::raw::pthread_t;
 #[doc(inline)]
 #[stable(feature = "raw_ext", since = "1.1.0")]
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 94c48be02ff..b99f4a2eacd 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -62,32 +62,31 @@ impl FileDesc {
     }
 
     #[cfg(not(any(target_env = "newlib", target_os = "solaris", target_os = "emscripten")))]
-    pub fn set_cloexec(&self) {
+    pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {
-            let ret = libc::ioctl(self.fd, libc::FIOCLEX);
-            debug_assert_eq!(ret, 0);
+            cvt(libc::ioctl(self.fd, libc::FIOCLEX))?;
+            Ok(())
         }
     }
     #[cfg(any(target_env = "newlib", target_os = "solaris", target_os = "emscripten"))]
-    pub fn set_cloexec(&self) {
+    pub fn set_cloexec(&self) -> io::Result<()> {
         unsafe {
-            let previous = libc::fcntl(self.fd, libc::F_GETFD);
-            let ret = libc::fcntl(self.fd, libc::F_SETFD, previous | libc::FD_CLOEXEC);
-            debug_assert_eq!(ret, 0);
+            let previous = cvt(libc::fcntl(self.fd, libc::F_GETFD))?;
+            cvt(libc::fcntl(self.fd, libc::F_SETFD, previous | libc::FD_CLOEXEC))?;
+            Ok(())
         }
     }
 
-    pub fn set_nonblocking(&self, nonblocking: bool) {
+    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         unsafe {
-            let previous = libc::fcntl(self.fd, libc::F_GETFL);
-            debug_assert!(previous != -1);
+            let previous = cvt(libc::fcntl(self.fd, libc::F_GETFL))?;
             let new = if nonblocking {
                 previous | libc::O_NONBLOCK
             } else {
                 previous & !libc::O_NONBLOCK
             };
-            let ret = libc::fcntl(self.fd, libc::F_SETFL, new);
-            debug_assert!(ret != -1);
+            cvt(libc::fcntl(self.fd, libc::F_SETFL, new))?;
+            Ok(())
         }
     }
 
@@ -114,8 +113,8 @@ impl FileDesc {
 
         let make_filedesc = |fd| {
             let fd = FileDesc::new(fd);
-            fd.set_cloexec();
-            fd
+            fd.set_cloexec()?;
+            Ok(fd)
         };
         static TRY_CLOEXEC: AtomicBool =
             AtomicBool::new(!cfg!(target_os = "android"));
@@ -127,7 +126,7 @@ impl FileDesc {
                 // though it reported doing so on F_DUPFD_CLOEXEC.
                 Ok(fd) => {
                     return Ok(if cfg!(target_os = "linux") {
-                        make_filedesc(fd)
+                        make_filedesc(fd)?
                     } else {
                         FileDesc::new(fd)
                     })
@@ -138,7 +137,7 @@ impl FileDesc {
                 Err(e) => return Err(e),
             }
         }
-        cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).map(make_filedesc)
+        cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).and_then(make_filedesc)
     }
 }
 
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 0969a59ea43..b315e676263 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -84,7 +84,7 @@ pub struct OpenOptions {
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct FilePermissions { mode: mode_t }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct FileType { mode: mode_t }
 
 pub struct DirBuilder { mode: mode_t }
@@ -100,31 +100,6 @@ impl FileAttr {
     }
 }
 
-#[cfg(any(target_os = "ios", target_os = "macos"))]
-// FIXME: update SystemTime to store a timespec and don't lose precision
-impl FileAttr {
-    pub fn modified(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(libc::timeval {
-            tv_sec: self.stat.st_mtime,
-            tv_usec: (self.stat.st_mtime_nsec / 1000) as libc::suseconds_t,
-        }))
-    }
-
-    pub fn accessed(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(libc::timeval {
-            tv_sec: self.stat.st_atime,
-            tv_usec: (self.stat.st_atime_nsec / 1000) as libc::suseconds_t,
-        }))
-    }
-
-    pub fn created(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(libc::timeval {
-            tv_sec: self.stat.st_birthtime,
-            tv_usec: (self.stat.st_birthtime_nsec / 1000) as libc::suseconds_t,
-        }))
-    }
-}
-
 #[cfg(target_os = "netbsd")]
 impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
@@ -149,7 +124,7 @@ impl FileAttr {
     }
 }
 
-#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "netbsd")))]
+#[cfg(not(target_os = "netbsd"))]
 impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
@@ -167,7 +142,9 @@ impl FileAttr {
 
     #[cfg(any(target_os = "bitrig",
               target_os = "freebsd",
-              target_os = "openbsd"))]
+              target_os = "openbsd",
+              target_os = "macos",
+              target_os = "ios"))]
     pub fn created(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_birthtime as libc::time_t,
@@ -177,7 +154,9 @@ impl FileAttr {
 
     #[cfg(not(any(target_os = "bitrig",
                   target_os = "freebsd",
-                  target_os = "openbsd")))]
+                  target_os = "openbsd",
+                  target_os = "macos",
+                  target_os = "ios")))]
     pub fn created(&self) -> io::Result<SystemTime> {
         Err(io::Error::new(io::ErrorKind::Other,
                            "creation time is not available on this platform \
@@ -226,9 +205,15 @@ impl Iterator for ReadDir {
                 // of the thread safety, on Illumos the readdir(3C) function is safe to use
                 // in threaded applications and it is generally preferred over the
                 // readdir_r(3C) function.
+                super::os::set_errno(0);
                 let entry_ptr = libc::readdir(self.dirp.0);
                 if entry_ptr.is_null() {
-                    return None
+                    // NULL can mean either the end is reached or an error occurred.
+                    // So we had to clear errno beforehand to check for an error now.
+                    return match super::os::errno() {
+                        0 => None,
+                        e => Some(Err(Error::from_raw_os_error(e))),
+                    }
                 }
 
                 let name = (*entry_ptr).d_name.as_ptr();
@@ -439,7 +424,7 @@ impl File {
         // The CLOEXEC flag, however, is supported on versions of OSX/BSD/etc
         // that we support, so we only do this on Linux currently.
         if cfg!(target_os = "linux") {
-            fd.set_cloexec();
+            fd.set_cloexec()?;
         }
 
         Ok(File(fd))
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 12a877f7478..f0fd42fc99b 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -12,8 +12,6 @@
 
 use io::{self, ErrorKind};
 use libc;
-use num::One;
-use ops::Neg;
 
 #[cfg(target_os = "android")]   pub use os::android as platform;
 #[cfg(target_os = "bitrig")]    pub use os::bitrig as platform;
@@ -123,9 +121,23 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
     }
 }
 
-pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
-    let one: T = T::one();
-    if t == -one {
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
+pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
+    if t.is_minus_one() {
         Err(io::Error::last_os_error())
     } else {
         Ok(t)
@@ -133,7 +145,8 @@ pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
 }
 
 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-    where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
+    where T: IsMinusOne,
+          F: FnMut() -> T
 {
     loop {
         match cvt(f()) {
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
index 4e4abcfbeee..52cf3f97c5c 100644
--- a/src/libstd/sys/unix/mutex.rs
+++ b/src/libstd/sys/unix/mutex.rs
@@ -30,6 +30,39 @@ impl Mutex {
         Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
     }
     #[inline]
+    pub unsafe fn init(&mut self) {
+        // Issue #33770
+        //
+        // A pthread mutex initialized with PTHREAD_MUTEX_INITIALIZER will have
+        // a type of PTHREAD_MUTEX_DEFAULT, which has undefined behavior if you
+        // try to re-lock it from the same thread when you already hold a lock.
+        //
+        // In practice, glibc takes advantage of this undefined behavior to
+        // implement hardware lock elision, which uses hardware transactional
+        // memory to avoid acquiring the lock. While a transaction is in
+        // progress, the lock appears to be unlocked. This isn't a problem for
+        // other threads since the transactional memory will abort if a conflict
+        // is detected, however no abort is generated if re-locking from the
+        // same thread.
+        //
+        // Since locking the same mutex twice will result in two aliasing &mut
+        // references, we instead create the mutex with type
+        // PTHREAD_MUTEX_NORMAL which is guaranteed to deadlock if we try to
+        // re-lock it from the same thread, thus avoiding undefined behavior.
+        //
+        // We can't do anything for StaticMutex, but that type is deprecated
+        // anyways.
+        let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
+        let r = libc::pthread_mutexattr_init(&mut attr);
+        debug_assert_eq!(r, 0);
+        let r = libc::pthread_mutexattr_settype(&mut attr, libc::PTHREAD_MUTEX_NORMAL);
+        debug_assert_eq!(r, 0);
+        let r = libc::pthread_mutex_init(self.inner.get(), &attr);
+        debug_assert_eq!(r, 0);
+        let r = libc::pthread_mutexattr_destroy(&mut attr);
+        debug_assert_eq!(r, 0);
+    }
+    #[inline]
     pub unsafe fn lock(&self) {
         let r = libc::pthread_mutex_lock(self.inner.get());
         debug_assert_eq!(r, 0);
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 830957a7e59..a784741c88c 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -77,7 +77,7 @@ impl Socket {
 
             let fd = cvt(libc::socket(fam, ty, 0))?;
             let fd = FileDesc::new(fd);
-            fd.set_cloexec();
+            fd.set_cloexec()?;
             Ok(Socket(fd))
         }
     }
@@ -99,9 +99,9 @@ impl Socket {
 
             cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
             let a = FileDesc::new(fds[0]);
-            a.set_cloexec();
             let b = FileDesc::new(fds[1]);
-            b.set_cloexec();
+            a.set_cloexec()?;
+            b.set_cloexec()?;
             Ok((Socket(a), Socket(b)))
         }
     }
@@ -132,7 +132,7 @@ impl Socket {
             libc::accept(self.0.raw(), storage, len)
         })?;
         let fd = FileDesc::new(fd);
-        fd.set_cloexec();
+        fd.set_cloexec()?;
         Ok(Socket(fd))
     }
 
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 94ebbd70ae8..4c3558f91f5 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -27,36 +27,45 @@ use path::{self, PathBuf};
 use ptr;
 use slice;
 use str;
-use sync::StaticMutex;
+use sys_common::mutex::Mutex;
 use sys::cvt;
 use sys::fd;
 use vec;
 
 const TMPBUF_SZ: usize = 128;
-static ENV_LOCK: StaticMutex = StaticMutex::new();
+static ENV_LOCK: Mutex = Mutex::new();
+
+
+extern {
+    #[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
+               link_name = "__errno_location")]
+    #[cfg_attr(any(target_os = "bitrig",
+                   target_os = "netbsd",
+                   target_os = "openbsd",
+                   target_os = "android",
+                   target_env = "newlib"),
+               link_name = "__errno")]
+    #[cfg_attr(target_os = "solaris", link_name = "___errno")]
+    #[cfg_attr(any(target_os = "macos",
+                   target_os = "ios",
+                   target_os = "freebsd"),
+               link_name = "__error")]
+    fn errno_location() -> *mut c_int;
+}
 
 /// Returns the platform-specific value of errno
 #[cfg(not(target_os = "dragonfly"))]
 pub fn errno() -> i32 {
-    extern {
-        #[cfg_attr(any(target_os = "linux", target_os = "emscripten"),
-                   link_name = "__errno_location")]
-        #[cfg_attr(any(target_os = "bitrig",
-                       target_os = "netbsd",
-                       target_os = "openbsd",
-                       target_os = "android",
-                       target_env = "newlib"),
-                   link_name = "__errno")]
-        #[cfg_attr(target_os = "solaris", link_name = "___errno")]
-        #[cfg_attr(any(target_os = "macos",
-                       target_os = "ios",
-                       target_os = "freebsd"),
-                   link_name = "__error")]
-        fn errno_location() -> *const c_int;
+    unsafe {
+        (*errno_location()) as i32
     }
+}
 
+/// Sets the platform-specific value of errno
+#[cfg(target_os = "solaris")] // only needed for readdir so far
+pub fn set_errno(e: i32) {
     unsafe {
-        (*errno_location()) as i32
+        *errno_location() = e as c_int
     }
 }
 
@@ -227,11 +236,11 @@ pub fn current_exe() -> io::Result<PathBuf> {
                        libc::KERN_PROC_ARGV];
         let mib = mib.as_mut_ptr();
         let mut argv_len = 0;
-        cvt(libc::sysctl(mib, 4, 0 as *mut _, &mut argv_len,
-                         0 as *mut _, 0))?;
+        cvt(libc::sysctl(mib, 4, ptr::null_mut(), &mut argv_len,
+                         ptr::null_mut(), 0))?;
         let mut argv = Vec::<*const libc::c_char>::with_capacity(argv_len as usize);
         cvt(libc::sysctl(mib, 4, argv.as_mut_ptr() as *mut _,
-                         &mut argv_len, 0 as *mut _, 0))?;
+                         &mut argv_len, ptr::null_mut(), 0))?;
         argv.set_len(argv_len as usize);
         if argv[0].is_null() {
             return Err(io::Error::new(io::ErrorKind::Other,
@@ -308,6 +317,10 @@ impl ExactSizeIterator for Args {
     fn len(&self) -> usize { self.iter.len() }
 }
 
+impl DoubleEndedIterator for Args {
+    fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
+}
+
 /// Returns the command line arguments
 ///
 /// Returns a list of the command line arguments.
@@ -434,10 +447,11 @@ pub unsafe fn environ() -> *mut *const *const c_char {
 /// Returns a vector of (variable, value) byte-vector pairs for all the
 /// environment variables of the current process.
 pub fn env() -> Env {
-    let _g = ENV_LOCK.lock();
-    return unsafe {
+    unsafe {
+        ENV_LOCK.lock();
         let mut environ = *environ();
         if environ == ptr::null() {
+            ENV_LOCK.unlock();
             panic!("os::env() failure getting env string from OS: {}",
                    io::Error::last_os_error());
         }
@@ -448,8 +462,13 @@ pub fn env() -> Env {
             }
             environ = environ.offset(1);
         }
-        Env { iter: result.into_iter(), _dont_send_or_sync_me: ptr::null_mut() }
-    };
+        let ret = Env {
+            iter: result.into_iter(),
+            _dont_send_or_sync_me: ptr::null_mut(),
+        };
+        ENV_LOCK.unlock();
+        return ret
+    }
 
     fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
         // Strategy (copied from glibc): Variable name and value are separated
@@ -471,32 +490,40 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
     // environment variables with a nul byte can't be set, so their value is
     // always None as well
     let k = CString::new(k.as_bytes())?;
-    let _g = ENV_LOCK.lock();
-    Ok(unsafe {
+    unsafe {
+        ENV_LOCK.lock();
         let s = libc::getenv(k.as_ptr()) as *const _;
-        if s.is_null() {
+        let ret = if s.is_null() {
             None
         } else {
             Some(OsStringExt::from_vec(CStr::from_ptr(s).to_bytes().to_vec()))
-        }
-    })
+        };
+        ENV_LOCK.unlock();
+        return Ok(ret)
+    }
 }
 
 pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
     let k = CString::new(k.as_bytes())?;
     let v = CString::new(v.as_bytes())?;
-    let _g = ENV_LOCK.lock();
-    cvt(unsafe {
-        libc::setenv(k.as_ptr(), v.as_ptr(), 1)
-    }).map(|_| ())
+
+    unsafe {
+        ENV_LOCK.lock();
+        let ret = cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(|_| ());
+        ENV_LOCK.unlock();
+        return ret
+    }
 }
 
 pub fn unsetenv(n: &OsStr) -> io::Result<()> {
     let nbuf = CString::new(n.as_bytes())?;
-    let _g = ENV_LOCK.lock();
-    cvt(unsafe {
-        libc::unsetenv(nbuf.as_ptr())
-    }).map(|_| ())
+
+    unsafe {
+        ENV_LOCK.lock();
+        let ret = cvt(libc::unsetenv(nbuf.as_ptr())).map(|_| ());
+        ENV_LOCK.unlock();
+        return ret
+    }
 }
 
 pub fn page_size() -> usize {
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index beca2d46753..01059413338 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -14,6 +14,7 @@ use cmp;
 use io;
 use libc::{self, c_int};
 use mem;
+use ptr;
 use sys::cvt_r;
 use sys::fd::FileDesc;
 
@@ -44,17 +45,18 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
         }
     }
     if unsafe { libc::pipe(fds.as_mut_ptr()) == 0 } {
-        Ok((AnonPipe::from_fd(fds[0]), AnonPipe::from_fd(fds[1])))
+        let fd0 = FileDesc::new(fds[0]);
+        let fd1 = FileDesc::new(fds[1]);
+        Ok((AnonPipe::from_fd(fd0)?, AnonPipe::from_fd(fd1)?))
     } else {
         Err(io::Error::last_os_error())
     }
 }
 
 impl AnonPipe {
-    pub fn from_fd(fd: libc::c_int) -> AnonPipe {
-        let fd = FileDesc::new(fd);
-        fd.set_cloexec();
-        AnonPipe(fd)
+    pub fn from_fd(fd: FileDesc) -> io::Result<AnonPipe> {
+        fd.set_cloexec()?;
+        Ok(AnonPipe(fd))
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
@@ -81,8 +83,8 @@ pub fn read2(p1: AnonPipe,
     // in the `select` loop below, and we wouldn't want one to block the other!
     let p1 = p1.into_fd();
     let p2 = p2.into_fd();
-    p1.set_nonblocking(true);
-    p2.set_nonblocking(true);
+    p1.set_nonblocking(true)?;
+    p2.set_nonblocking(true)?;
 
     let max = cmp::max(p1.raw(), p2.raw());
     loop {
@@ -91,8 +93,8 @@ pub fn read2(p1: AnonPipe,
             let mut read: libc::fd_set = mem::zeroed();
             libc::FD_SET(p1.raw(), &mut read);
             libc::FD_SET(p2.raw(), &mut read);
-            libc::select(max + 1, &mut read, 0 as *mut _, 0 as *mut _,
-                         0 as *mut _)
+            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
+                         ptr::null_mut())
         })?;
 
         // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
@@ -114,11 +116,11 @@ pub fn read2(p1: AnonPipe,
             }
         };
         if read(&p1, v1)? {
-            p2.set_nonblocking(false);
+            p2.set_nonblocking(false)?;
             return p2.read_to_end(v2).map(|_| ());
         }
         if read(&p2, v2)? {
-            p1.set_nonblocking(false);
+            p1.set_nonblocking(false)?;
             return p1.read_to_end(v1).map(|_| ());
         }
     }
diff --git a/src/libstd/sys/unix/process.rs b/src/libstd/sys/unix/process.rs
index 270c2096b2c..d68867fb3d2 100644
--- a/src/libstd/sys/unix/process.rs
+++ b/src/libstd/sys/unix/process.rs
@@ -55,7 +55,6 @@ pub struct Command {
     cwd: Option<CString>,
     uid: Option<uid_t>,
     gid: Option<gid_t>,
-    session_leader: bool,
     saw_nul: bool,
     closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>,
     stdin: Option<Stdio>,
@@ -97,7 +96,7 @@ impl Command {
         let mut saw_nul = false;
         let program = os2c(program, &mut saw_nul);
         Command {
-            argv: vec![program.as_ptr(), 0 as *const _],
+            argv: vec![program.as_ptr(), ptr::null()],
             program: program,
             args: Vec::new(),
             env: None,
@@ -105,7 +104,6 @@ impl Command {
             cwd: None,
             uid: None,
             gid: None,
-            session_leader: false,
             saw_nul: saw_nul,
             closures: Vec::new(),
             stdin: None,
@@ -119,7 +117,7 @@ impl Command {
         // pointer.
         let arg = os2c(arg, &mut self.saw_nul);
         self.argv[self.args.len() + 1] = arg.as_ptr();
-        self.argv.push(0 as *const _);
+        self.argv.push(ptr::null());
 
         // Also make sure we keep track of the owned value to schedule a
         // destructor for this memory.
@@ -136,7 +134,7 @@ impl Command {
                 envp.push(s.as_ptr());
                 map.insert(k, (envp.len() - 1, s));
             }
-            envp.push(0 as *const _);
+            envp.push(ptr::null());
             self.env = Some(map);
             self.envp = Some(envp);
         }
@@ -147,7 +145,7 @@ impl Command {
         let new_key = pair_to_key(key, val, &mut self.saw_nul);
         let (map, envp) = self.init_env_map();
 
-        // If `key` is already present then we we just update `envp` in place
+        // If `key` is already present then we just update `envp` in place
         // (and store the owned value), but if it's not there we override the
         // trailing NULL pointer, add a new NULL pointer, and store where we
         // were located.
@@ -160,7 +158,7 @@ impl Command {
             Entry::Vacant(e) => {
                 let len = envp.len();
                 envp[len - 1] = new_key.as_ptr();
-                envp.push(0 as *const _);
+                envp.push(ptr::null());
                 e.insert((len - 1, new_key));
             }
         }
@@ -185,7 +183,7 @@ impl Command {
 
     pub fn env_clear(&mut self) {
         self.env = Some(HashMap::new());
-        self.envp = Some(vec![0 as *const _]);
+        self.envp = Some(vec![ptr::null()]);
     }
 
     pub fn cwd(&mut self, dir: &OsStr) {
@@ -197,9 +195,6 @@ impl Command {
     pub fn gid(&mut self, id: gid_t) {
         self.gid = Some(id);
     }
-    pub fn session_leader(&mut self, session_leader: bool) {
-        self.session_leader = session_leader;
-    }
 
     pub fn before_exec(&mut self,
                        f: Box<FnMut() -> io::Result<()> + Send + Sync>) {
@@ -367,12 +362,6 @@ impl Command {
 
             t!(cvt(libc::setuid(u as uid_t)));
         }
-        if self.session_leader {
-            // Don't check the error of setsid because it fails if we're the
-            // process leader already. We just forked so it shouldn't return
-            // error, but ignore it anyway.
-            let _ = libc::setsid();
-        }
         if let Some(ref cwd) = self.cwd {
             t!(cvt(libc::chdir(cwd.as_ptr())));
         }
@@ -550,6 +539,12 @@ impl ExitStatus {
     }
 }
 
+impl From<c_int> for ExitStatus {
+    fn from(a: c_int) -> ExitStatus {
+        ExitStatus(a)
+    }
+}
+
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if let Some(code) = self.code() {
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index 92c3bf8829a..25a7a3ce50d 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -41,8 +41,10 @@ mod imp {
         #[cfg(target_arch = "aarch64")]
         const NR_GETRANDOM: libc::c_long = 278;
 
+        const GRND_NONBLOCK: libc::c_uint = 0x0001;
+
         unsafe {
-            libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
+            libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)
         }
     }
 
@@ -63,6 +65,19 @@ mod imp {
                 let err = errno() as libc::c_int;
                 if err == libc::EINTR {
                     continue;
+                } else if err == libc::EAGAIN {
+                    // if getrandom() returns EAGAIN it would have blocked
+                    // because the non-blocking pool (urandom) has not
+                    // initialized in the kernel yet due to a lack of entropy
+                    // the fallback we do here is to avoid blocking applications
+                    // which could depend on this call without ever knowing
+                    // they do and don't have a work around. The PRNG of
+                    // /dev/urandom will still be used but not over a completely
+                    // full entropy pool
+                    let reader = File::open("/dev/urandom").expect("Unable to open /dev/urandom");
+                    let mut reader_rng = ReaderRng::new(reader);
+                    reader_rng.fill_bytes(& mut v[read..]);
+                    read += v.len() as usize;
                 } else {
                     panic!("unexpected getrandom error: {}", err);
                 }
diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs
index 44bd5d895f2..fbd4e1d1208 100644
--- a/src/libstd/sys/unix/rwlock.rs
+++ b/src/libstd/sys/unix/rwlock.rs
@@ -10,15 +10,24 @@
 
 use libc;
 use cell::UnsafeCell;
+use sync::atomic::{AtomicUsize, Ordering};
 
-pub struct RWLock { inner: UnsafeCell<libc::pthread_rwlock_t> }
+pub struct RWLock {
+    inner: UnsafeCell<libc::pthread_rwlock_t>,
+    write_locked: UnsafeCell<bool>,
+    num_readers: AtomicUsize,
+}
 
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
 impl RWLock {
     pub const fn new() -> RWLock {
-        RWLock { inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER) }
+        RWLock {
+            inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER),
+            write_locked: UnsafeCell::new(false),
+            num_readers: AtomicUsize::new(0),
+        }
     }
     #[inline]
     pub unsafe fn read(&self) {
@@ -35,37 +44,86 @@ impl RWLock {
         //
         // We roughly maintain the deadlocking behavior by panicking to ensure
         // that this lock acquisition does not succeed.
-        if r == libc::EDEADLK {
+        //
+        // We also check whether there this lock is already write locked. This
+        // is only possible if it was write locked by the current thread and
+        // the implementation allows recursive locking. The POSIX standard
+        // doesn't require recursivly locking a rwlock to deadlock, but we can't
+        // allow that because it could lead to aliasing issues.
+        if r == libc::EDEADLK || *self.write_locked.get() {
+            if r == 0 {
+                self.raw_unlock();
+            }
             panic!("rwlock read lock would result in deadlock");
         } else {
             debug_assert_eq!(r, 0);
+            self.num_readers.fetch_add(1, Ordering::Relaxed);
         }
     }
     #[inline]
     pub unsafe fn try_read(&self) -> bool {
-        libc::pthread_rwlock_tryrdlock(self.inner.get()) == 0
+        let r = libc::pthread_rwlock_tryrdlock(self.inner.get());
+        if r == 0 {
+            if *self.write_locked.get() {
+                self.raw_unlock();
+                false
+            } else {
+                self.num_readers.fetch_add(1, Ordering::Relaxed);
+                true
+            }
+        } else {
+            false
+        }
     }
     #[inline]
     pub unsafe fn write(&self) {
         let r = libc::pthread_rwlock_wrlock(self.inner.get());
-        // see comments above for why we check for EDEADLK
-        if r == libc::EDEADLK {
+        // See comments above for why we check for EDEADLK and write_locked. We
+        // also need to check that num_readers is 0.
+        if r == libc::EDEADLK || *self.write_locked.get() ||
+           self.num_readers.load(Ordering::Relaxed) != 0 {
+            if r == 0 {
+                self.raw_unlock();
+            }
             panic!("rwlock write lock would result in deadlock");
         } else {
             debug_assert_eq!(r, 0);
         }
+        *self.write_locked.get() = true;
     }
     #[inline]
     pub unsafe fn try_write(&self) -> bool {
-        libc::pthread_rwlock_trywrlock(self.inner.get()) == 0
+        let r = libc::pthread_rwlock_trywrlock(self.inner.get());
+        if r == 0 {
+            if *self.write_locked.get() || self.num_readers.load(Ordering::Relaxed) != 0 {
+                self.raw_unlock();
+                false
+            } else {
+                *self.write_locked.get() = true;
+                true
+            }
+        } else {
+            false
+        }
     }
     #[inline]
-    pub unsafe fn read_unlock(&self) {
+    unsafe fn raw_unlock(&self) {
         let r = libc::pthread_rwlock_unlock(self.inner.get());
         debug_assert_eq!(r, 0);
     }
     #[inline]
-    pub unsafe fn write_unlock(&self) { self.read_unlock() }
+    pub unsafe fn read_unlock(&self) {
+        debug_assert!(!*self.write_locked.get());
+        self.num_readers.fetch_sub(1, Ordering::Relaxed);
+        self.raw_unlock();
+    }
+    #[inline]
+    pub unsafe fn write_unlock(&self) {
+        debug_assert_eq!(self.num_readers.load(Ordering::Relaxed), 0);
+        debug_assert!(*self.write_locked.get());
+        *self.write_locked.get() = false;
+        self.raw_unlock();
+    }
     #[inline]
     pub unsafe fn destroy(&self) {
         let r = libc::pthread_rwlock_destroy(self.inner.get());
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index cb34d1a5fbc..1061ca87f64 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -12,7 +12,6 @@ use prelude::v1::*;
 
 use alloc::boxed::FnBox;
 use cmp;
-#[cfg(not(any(target_env = "newlib", target_os = "solaris")))]
 use ffi::CStr;
 use io;
 use libc;
@@ -125,16 +124,25 @@ impl Thread {
     }
 
     pub fn sleep(dur: Duration) {
-        let mut ts = libc::timespec {
-            tv_sec: dur.as_secs() as libc::time_t,
-            tv_nsec: dur.subsec_nanos() as libc::c_long,
-        };
+        let mut secs = dur.as_secs();
+        let mut nsecs = dur.subsec_nanos() as libc::c_long;
 
         // If we're awoken with a signal then the return value will be -1 and
         // nanosleep will fill in `ts` with the remaining time.
         unsafe {
-            while libc::nanosleep(&ts, &mut ts) == -1 {
-                assert_eq!(os::errno(), libc::EINTR);
+            while secs > 0 || nsecs > 0 {
+                let mut ts = libc::timespec {
+                    tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t,
+                    tv_nsec: nsecs,
+                };
+                secs -= ts.tv_sec as u64;
+                if libc::nanosleep(&ts, &mut ts) == -1 {
+                    assert_eq!(os::errno(), libc::EINTR);
+                    secs += ts.tv_sec as u64;
+                    nsecs = ts.tv_nsec;
+                } else {
+                    nsecs = 0;
+                }
             }
         }
     }
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index cc7abe25e35..a08cec38f73 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -8,37 +8,129 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use cmp::Ordering;
+use libc;
+use time::Duration;
+
 pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};
 
 const NSEC_PER_SEC: u64 = 1_000_000_000;
 
+#[derive(Copy, Clone)]
+struct Timespec {
+    t: libc::timespec,
+}
+
+impl Timespec {
+    fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
+        if self >= other {
+            Ok(if self.t.tv_nsec >= other.t.tv_nsec {
+                Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
+                              (self.t.tv_nsec - other.t.tv_nsec) as u32)
+            } else {
+                Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
+                              self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
+                              other.t.tv_nsec as u32)
+            })
+        } else {
+            match other.sub_timespec(self) {
+                Ok(d) => Err(d),
+                Err(d) => Ok(d),
+            }
+        }
+    }
+
+    fn add_duration(&self, other: &Duration) -> Timespec {
+        let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
+        let mut secs = secs.expect("overflow when adding duration to time");
+
+        // Nano calculations can't overflow because nanos are <1B which fit
+        // in a u32.
+        let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
+        if nsec >= NSEC_PER_SEC as u32 {
+            nsec -= NSEC_PER_SEC as u32;
+            secs = secs.checked_add(1).expect("overflow when adding \
+                                               duration to time");
+        }
+        Timespec {
+            t: libc::timespec {
+                tv_sec: secs as libc::time_t,
+                tv_nsec: nsec as libc::c_long,
+            },
+        }
+    }
+
+    fn sub_duration(&self, other: &Duration) -> Timespec {
+        let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
+        let mut secs = secs.expect("overflow when subtracting duration \
+                                    from time");
+
+        // Similar to above, nanos can't overflow.
+        let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
+        if nsec < 0 {
+            nsec += NSEC_PER_SEC as i32;
+            secs = secs.checked_sub(1).expect("overflow when subtracting \
+                                               duration from time");
+        }
+        Timespec {
+            t: libc::timespec {
+                tv_sec: secs as libc::time_t,
+                tv_nsec: nsec as libc::c_long,
+            },
+        }
+    }
+}
+
+impl PartialEq for Timespec {
+    fn eq(&self, other: &Timespec) -> bool {
+        self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
+    }
+}
+
+impl Eq for Timespec {}
+
+impl PartialOrd for Timespec {
+    fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Timespec {
+    fn cmp(&self, other: &Timespec) -> Ordering {
+        let me = (self.t.tv_sec, self.t.tv_nsec);
+        let other = (other.t.tv_sec, other.t.tv_nsec);
+        me.cmp(&other)
+    }
+}
+
 #[cfg(any(target_os = "macos", target_os = "ios"))]
 mod inner {
-    use cmp::Ordering;
     use fmt;
     use libc;
-    use super::NSEC_PER_SEC;
     use sync::Once;
     use sys::cvt;
     use sys_common::mul_div_u64;
     use time::Duration;
 
-    const USEC_PER_SEC: u64 = NSEC_PER_SEC / 1000;
+    use super::NSEC_PER_SEC;
+    use super::Timespec;
 
     #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
     pub struct Instant {
         t: u64
     }
 
-    #[derive(Copy, Clone)]
+    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct SystemTime {
-        t: libc::timeval,
+        t: Timespec,
     }
 
     pub const UNIX_EPOCH: SystemTime = SystemTime {
-        t: libc::timeval {
-            tv_sec: 0,
-            tv_usec: 0,
+        t: Timespec {
+            t: libc::timespec {
+                tv_sec: 0,
+                tv_nsec: 0,
+            },
         },
     };
 
@@ -72,113 +164,52 @@ mod inner {
 
     impl SystemTime {
         pub fn now() -> SystemTime {
-            let mut s = SystemTime {
-                t: libc::timeval {
-                    tv_sec: 0,
-                    tv_usec: 0,
-                },
+            use ptr;
+
+            let mut s = libc::timeval {
+                tv_sec: 0,
+                tv_usec: 0,
             };
             cvt(unsafe {
-                libc::gettimeofday(&mut s.t, 0 as *mut _)
+                libc::gettimeofday(&mut s, ptr::null_mut())
             }).unwrap();
-            return s
+            return SystemTime::from(s)
         }
 
         pub fn sub_time(&self, other: &SystemTime)
                         -> Result<Duration, Duration> {
-            if self >= other {
-                Ok(if self.t.tv_usec >= other.t.tv_usec {
-                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
-                                  ((self.t.tv_usec -
-                                    other.t.tv_usec) as u32) * 1000)
-                } else {
-                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
-                                  (self.t.tv_usec as u32 + (USEC_PER_SEC as u32) -
-                                   other.t.tv_usec as u32) * 1000)
-                })
-            } else {
-                match other.sub_time(self) {
-                    Ok(d) => Err(d),
-                    Err(d) => Ok(d),
-                }
-            }
+            self.t.sub_timespec(&other.t)
         }
 
         pub fn add_duration(&self, other: &Duration) -> SystemTime {
-            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when adding duration to time");
-
-            // Nano calculations can't overflow because nanos are <1B which fit
-            // in a u32.
-            let mut usec = (other.subsec_nanos() / 1000) + self.t.tv_usec as u32;
-            if usec >= USEC_PER_SEC as u32 {
-                usec -= USEC_PER_SEC as u32;
-                secs = secs.checked_add(1).expect("overflow when adding \
-                                                   duration to time");
-            }
-            SystemTime {
-                t: libc::timeval {
-                    tv_sec: secs as libc::time_t,
-                    tv_usec: usec as libc::suseconds_t,
-                },
-            }
+            SystemTime { t: self.t.add_duration(other) }
         }
 
         pub fn sub_duration(&self, other: &Duration) -> SystemTime {
-            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when subtracting duration \
-                                        from time");
-
-            // Similar to above, nanos can't overflow.
-            let mut usec = self.t.tv_usec as i32 -
-                           (other.subsec_nanos() / 1000) as i32;
-            if usec < 0 {
-                usec += USEC_PER_SEC as i32;
-                secs = secs.checked_sub(1).expect("overflow when subtracting \
-                                                   duration from time");
-            }
-            SystemTime {
-                t: libc::timeval {
-                    tv_sec: secs as libc::time_t,
-                    tv_usec: usec as libc::suseconds_t,
-                },
-            }
+            SystemTime { t: self.t.sub_duration(other) }
         }
     }
 
     impl From<libc::timeval> for SystemTime {
         fn from(t: libc::timeval) -> SystemTime {
-            SystemTime { t: t }
-        }
-    }
-
-    impl PartialEq for SystemTime {
-        fn eq(&self, other: &SystemTime) -> bool {
-            self.t.tv_sec == other.t.tv_sec && self.t.tv_usec == other.t.tv_usec
-        }
-    }
-
-    impl Eq for SystemTime {}
-
-    impl PartialOrd for SystemTime {
-        fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
-            Some(self.cmp(other))
+            SystemTime::from(libc::timespec {
+                tv_sec: t.tv_sec,
+                tv_nsec: (t.tv_usec * 1000) as libc::c_long,
+            })
         }
     }
 
-    impl Ord for SystemTime {
-        fn cmp(&self, other: &SystemTime) -> Ordering {
-            let me = (self.t.tv_sec, self.t.tv_usec);
-            let other = (other.t.tv_sec, other.t.tv_usec);
-            me.cmp(&other)
+    impl From<libc::timespec> for SystemTime {
+        fn from(t: libc::timespec) -> SystemTime {
+            SystemTime { t: Timespec { t: t } }
         }
     }
 
     impl fmt::Debug for SystemTime {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             f.debug_struct("SystemTime")
-             .field("tv_sec", &self.t.tv_sec)
-             .field("tv_usec", &self.t.tv_usec)
+             .field("tv_sec", &self.t.t.tv_sec)
+             .field("tv_nsec", &self.t.t.tv_nsec)
              .finish()
         }
     }
@@ -209,17 +240,12 @@ mod inner {
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
 mod inner {
-    use cmp::Ordering;
     use fmt;
     use libc;
-    use super::NSEC_PER_SEC;
     use sys::cvt;
     use time::Duration;
 
-    #[derive(Copy, Clone)]
-    struct Timespec {
-        t: libc::timespec,
-    }
+    use super::Timespec;
 
     #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct Instant {
@@ -242,7 +268,7 @@ mod inner {
 
     impl Instant {
         pub fn now() -> Instant {
-            Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
+            Instant { t: now(libc::CLOCK_MONOTONIC) }
         }
 
         pub fn sub_instant(&self, other: &Instant) -> Duration {
@@ -271,7 +297,7 @@ mod inner {
 
     impl SystemTime {
         pub fn now() -> SystemTime {
-            SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
+            SystemTime { t: now(libc::CLOCK_REALTIME) }
         }
 
         pub fn sub_time(&self, other: &SystemTime)
@@ -308,98 +334,16 @@ mod inner {
     #[cfg(target_os = "dragonfly")]
     pub type clock_t = libc::c_ulong;
 
-    impl Timespec {
-        pub fn now(clock: clock_t) -> Timespec {
-            let mut t = Timespec {
-                t: libc::timespec {
-                    tv_sec: 0,
-                    tv_nsec: 0,
-                }
-            };
-            cvt(unsafe {
-                libc::clock_gettime(clock, &mut t.t)
-            }).unwrap();
-            t
-        }
-
-        fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
-            if self >= other {
-                Ok(if self.t.tv_nsec >= other.t.tv_nsec {
-                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
-                                  (self.t.tv_nsec - other.t.tv_nsec) as u32)
-                } else {
-                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
-                                  self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
-                                  other.t.tv_nsec as u32)
-                })
-            } else {
-                match other.sub_timespec(self) {
-                    Ok(d) => Err(d),
-                    Err(d) => Ok(d),
-                }
-            }
-        }
-
-        fn add_duration(&self, other: &Duration) -> Timespec {
-            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when adding duration to time");
-
-            // Nano calculations can't overflow because nanos are <1B which fit
-            // in a u32.
-            let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
-            if nsec >= NSEC_PER_SEC as u32 {
-                nsec -= NSEC_PER_SEC as u32;
-                secs = secs.checked_add(1).expect("overflow when adding \
-                                                   duration to time");
-            }
-            Timespec {
-                t: libc::timespec {
-                    tv_sec: secs as libc::time_t,
-                    tv_nsec: nsec as libc::c_long,
-                },
-            }
-        }
-
-        fn sub_duration(&self, other: &Duration) -> Timespec {
-            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
-            let mut secs = secs.expect("overflow when subtracting duration \
-                                        from time");
-
-            // Similar to above, nanos can't overflow.
-            let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
-            if nsec < 0 {
-                nsec += NSEC_PER_SEC as i32;
-                secs = secs.checked_sub(1).expect("overflow when subtracting \
-                                                   duration from time");
-            }
-            Timespec {
-                t: libc::timespec {
-                    tv_sec: secs as libc::time_t,
-                    tv_nsec: nsec as libc::c_long,
-                },
+    fn now(clock: clock_t) -> Timespec {
+        let mut t = Timespec {
+            t: libc::timespec {
+                tv_sec: 0,
+                tv_nsec: 0,
             }
-        }
-    }
-
-    impl PartialEq for Timespec {
-        fn eq(&self, other: &Timespec) -> bool {
-            self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
-        }
-    }
-
-    impl Eq for Timespec {}
-
-    impl PartialOrd for Timespec {
-        fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
-            Some(self.cmp(other))
-        }
-    }
-
-    impl Ord for Timespec {
-        fn cmp(&self, other: &Timespec) -> Ordering {
-            let me = (self.t.tv_sec, self.t.tv_nsec);
-            let other = (other.t.tv_sec, other.t.tv_nsec);
-            me.cmp(&other)
-        }
+        };
+        cvt(unsafe {
+            libc::clock_gettime(clock, &mut t.t)
+        }).unwrap();
+        t
     }
 }
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 0e10a8d8e8d..82a44c1c110 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -30,9 +30,9 @@ use io;
 use libc::c_void;
 use mem;
 use ptr;
-use sync::StaticMutex;
 use sys::c;
 use sys::dynamic_lib::DynamicLibrary;
+use sys::mutex::Mutex;
 
 macro_rules! sym {
     ($lib:expr, $e:expr, $t:ident) => (
@@ -101,53 +101,59 @@ impl Drop for Cleanup {
 pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
+        let res = _write(w);
+        LOCK.unlock();
+        return res
+    }
+}
 
+unsafe fn _write(w: &mut Write) -> io::Result<()> {
     let dbghelp = match DynamicLibrary::open("dbghelp.dll") {
         Ok(lib) => lib,
         Err(..) => return Ok(()),
     };
-    unsafe {
-        // Fetch the symbols necessary from dbghelp.dll
-        let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
-        let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
-        let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
-
-        // Allocate necessary structures for doing the stack walk
-        let process = c::GetCurrentProcess();
-        let thread = c::GetCurrentThread();
-        let mut context: c::CONTEXT = mem::zeroed();
-        c::RtlCaptureContext(&mut context);
-        let mut frame: c::STACKFRAME64 = mem::zeroed();
-        let image = init_frame(&mut frame, &context);
-
-        // Initialize this process's symbols
-        let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
-        if ret != c::TRUE { return Ok(()) }
-        let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
-
-        // And now that we're done with all the setup, do the stack walking!
-        // Start from -1 to avoid printing this stack frame, which will
-        // always be exactly the same.
-        let mut i = -1;
-        write!(w, "stack backtrace:\n")?;
-        while StackWalk64(image, process, thread, &mut frame, &mut context,
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut()) == c::TRUE {
-            let addr = frame.AddrPC.Offset;
-            if addr == frame.AddrReturn.Offset || addr == 0 ||
-               frame.AddrReturn.Offset == 0 { break }
-
-            i += 1;
-
-            if i >= 0 {
-                printing::print(w, i, addr - 1, process, &dbghelp)?;
-            }
-        }
 
-        Ok(())
+    // Fetch the symbols necessary from dbghelp.dll
+    let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
+    let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
+    let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
+
+    // Allocate necessary structures for doing the stack walk
+    let process = c::GetCurrentProcess();
+    let thread = c::GetCurrentThread();
+    let mut context: c::CONTEXT = mem::zeroed();
+    c::RtlCaptureContext(&mut context);
+    let mut frame: c::STACKFRAME64 = mem::zeroed();
+    let image = init_frame(&mut frame, &context);
+
+    // Initialize this process's symbols
+    let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
+    if ret != c::TRUE { return Ok(()) }
+    let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
+
+    // And now that we're done with all the setup, do the stack walking!
+    // Start from -1 to avoid printing this stack frame, which will
+    // always be exactly the same.
+    let mut i = -1;
+    write!(w, "stack backtrace:\n")?;
+    while StackWalk64(image, process, thread, &mut frame, &mut context,
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut()) == c::TRUE {
+        let addr = frame.AddrPC.Offset;
+        if addr == frame.AddrReturn.Offset || addr == 0 ||
+           frame.AddrReturn.Offset == 0 { break }
+
+        i += 1;
+
+        if i >= 0 {
+            printing::print(w, i, addr - 1, process, &dbghelp)?;
+        }
     }
+
+    Ok(())
 }
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index ab24b9e6fd6..ce563dc7b16 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -181,6 +181,7 @@ pub const ERROR_ACCESS_DENIED: DWORD = 5;
 pub const ERROR_INVALID_HANDLE: DWORD = 6;
 pub const ERROR_NO_MORE_FILES: DWORD = 18;
 pub const ERROR_HANDLE_EOF: DWORD = 38;
+pub const ERROR_FILE_EXISTS: DWORD = 80;
 pub const ERROR_BROKEN_PIPE: DWORD = 109;
 pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
 pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
@@ -277,21 +278,6 @@ pub const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
 pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
 pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
 pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub const EXCEPTION_NONCONTINUABLE: DWORD = 0x1;   // Noncontinuable exception
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub const EXCEPTION_UNWINDING: DWORD = 0x2;        // Unwind is in progress
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub const EXCEPTION_EXIT_UNWIND: DWORD = 0x4;      // Exit unwind is in progress
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub const EXCEPTION_TARGET_UNWIND: DWORD = 0x20;   // Target unwind in progress
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
-                                    EXCEPTION_EXIT_UNWIND |
-                                    EXCEPTION_TARGET_UNWIND |
-                                    EXCEPTION_COLLIDED_UNWIND;
 
 pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
 pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000;
@@ -813,31 +799,6 @@ pub struct in6_addr {
     pub s6_addr: [u8; 16],
 }
 
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub enum UNWIND_HISTORY_TABLE {}
-
-#[repr(C)]
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub struct RUNTIME_FUNCTION {
-    pub BeginAddress: DWORD,
-    pub EndAddress: DWORD,
-    pub UnwindData: DWORD,
-}
-
-#[repr(C)]
-#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-pub struct DISPATCHER_CONTEXT {
-    pub ControlPc: LPVOID,
-    pub ImageBase: LPVOID,
-    pub FunctionEntry: *const RUNTIME_FUNCTION,
-    pub EstablisherFrame: LPVOID,
-    pub TargetIp: LPVOID,
-    pub ContextRecord: *const CONTEXT,
-    pub LanguageHandler: LPVOID,
-    pub HandlerData: *const u8,
-    pub HistoryTable: *const UNWIND_HISTORY_TABLE,
-}
-
 #[repr(C)]
 #[derive(Copy, Clone)]
 #[allow(dead_code)] // we only use some variants
@@ -1113,19 +1074,6 @@ extern "system" {
                           pbBuffer: *mut BYTE) -> BOOL;
     pub fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
 
-    #[unwind]
-    #[cfg(any(target_arch = "x86_64", target_env = "msvc"))]
-    pub fn RaiseException(dwExceptionCode: DWORD,
-                          dwExceptionFlags: DWORD,
-                          nNumberOfArguments: DWORD,
-                          lpArguments: *const ULONG_PTR);
-    #[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
-    pub fn RtlUnwindEx(TargetFrame: LPVOID,
-                       TargetIp: LPVOID,
-                       ExceptionRecord: *const EXCEPTION_RECORD,
-                       ReturnValue: LPVOID,
-                       OriginalContext: *const CONTEXT,
-                       HistoryTable: *const UNWIND_HISTORY_TABLE);
     pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
 
     pub fn CreateEventW(lpEventAttributes: LPSECURITY_ATTRIBUTES,
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index d378a6853f3..4388a0bdff2 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -19,9 +19,7 @@ use sys;
 use sys_common::{AsInnerMut, AsInner};
 
 /// Windows-specific extensions to `OpenOptions`
-#[unstable(feature = "open_options_ext",
-           reason = "may require more thought/methods",
-           issue = "27720")]
+#[stable(feature = "open_options_ext", since = "1.10.0")]
 pub trait OpenOptionsExt {
     /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
     /// with the specified value.
@@ -34,7 +32,6 @@ pub trait OpenOptionsExt {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(open_options_ext)]
     /// use std::fs::OpenOptions;
     /// use std::os::windows::fs::OpenOptionsExt;
     ///
@@ -42,6 +39,7 @@ pub trait OpenOptionsExt {
     /// // to call `stat()` on the file
     /// let file = OpenOptions::new().access_mode(0).open("foo.txt");
     /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn access_mode(&mut self, access: u32) -> &mut Self;
 
     /// Overrides the `dwShareMode` argument to the call to `CreateFile` with
@@ -55,7 +53,6 @@ pub trait OpenOptionsExt {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(open_options_ext)]
     /// use std::fs::OpenOptions;
     /// use std::os::windows::fs::OpenOptionsExt;
     ///
@@ -65,6 +62,7 @@ pub trait OpenOptionsExt {
     ///                              .share_mode(0)
     ///                              .open("foo.txt");
     /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn share_mode(&mut self, val: u32) -> &mut Self;
 
     /// Sets extra flags for the `dwFileFlags` argument to the call to
@@ -88,9 +86,7 @@ pub trait OpenOptionsExt {
     /// }
     /// let file = options.open("foo.txt");
     /// ```
-    #[unstable(feature = "expand_open_options",
-               reason = "recently added",
-               issue = "30014")]
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn custom_flags(&mut self, flags: u32) -> &mut Self;
 
     /// Sets the `dwFileAttributes` argument to the call to `CreateFile2` to
@@ -111,7 +107,6 @@ pub trait OpenOptionsExt {
     /// # Examples
     ///
     /// ```rust,ignore
-    /// #![feature(open_options_ext)]
     /// extern crate winapi;
     /// use std::fs::OpenOptions;
     /// use std::os::windows::fs::OpenOptionsExt;
@@ -120,17 +115,17 @@ pub trait OpenOptionsExt {
     ///                              .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
     ///                              .open("foo.txt");
     /// ```
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn attributes(&mut self, val: u32) -> &mut Self;
 
     /// Sets the `dwSecurityQosFlags` argument to the call to `CreateFile2` to
     /// the specified value (or combines it with `custom_flags` and `attributes`
     /// to set the `dwFlagsAndAttributes` for `CreateFile`).
+    #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
 }
 
-#[unstable(feature = "open_options_ext",
-           reason = "may require more thought/methods",
-           issue = "27720")]
+#[stable(feature = "open_options_ext", since = "1.10.0")]
 impl OpenOptionsExt for OpenOptions {
     fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
         self.as_inner_mut().access_mode(access); self
diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs
index f6ee59eec32..56c6a73d4f8 100644
--- a/src/libstd/sys/windows/ext/process.rs
+++ b/src/libstd/sys/windows/ext/process.rs
@@ -81,3 +81,18 @@ impl IntoRawHandle for process::ChildStderr {
         self.into_inner().into_handle().into_raw() as *mut _
     }
 }
+
+/// Windows-specific extensions to `std::process::ExitStatus`
+#[unstable(feature = "exit_status_from", issue = "32713")]
+pub trait ExitStatusExt {
+    /// Creates a new `ExitStatus` from the raw underlying `u32` return value of
+    /// a process.
+    fn from_raw(raw: u32) -> Self;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ExitStatusExt for process::ExitStatus {
+    fn from_raw(raw: u32) -> Self {
+        process::ExitStatus::from_inner(From::from(raw))
+    }
+}
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 529e42248f6..2683e57256d 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use prelude::v1::*;
-use io::prelude::*;
 use os::windows::prelude::*;
 
 use ffi::OsString;
@@ -39,7 +38,7 @@ pub struct FileAttr {
     reparse_tag: c::DWORD,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub enum FileType {
     Dir, File, SymlinkFile, SymlinkDir, ReparsePoint, MountPoint,
 }
@@ -120,8 +119,8 @@ impl DirEntry {
     fn new(root: &Arc<PathBuf>, wfd: &c::WIN32_FIND_DATAW) -> Option<DirEntry> {
         match &wfd.cFileName[0..3] {
             // check for '.' and '..'
-            [46, 0, ..] |
-            [46, 46, 0, ..] => return None,
+            &[46, 0, ..] |
+            &[46, 46, 0, ..] => return None,
             _ => {}
         }
 
diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs
index 74546bb893b..d10abae2865 100644
--- a/src/libstd/sys/windows/handle.rs
+++ b/src/libstd/sys/windows/handle.rs
@@ -46,10 +46,10 @@ impl Handle {
 
     pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> {
         unsafe {
-            let event = c::CreateEventW(0 as *mut _,
+            let event = c::CreateEventW(ptr::null_mut(),
                                         manual as c::BOOL,
                                         init as c::BOOL,
-                                        0 as *const _);
+                                        ptr::null());
             if event.is_null() {
                 Err(io::Error::last_os_error())
             } else {
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 384940e4dc4..12219c1e9d4 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -14,7 +14,6 @@ use prelude::v1::*;
 
 use ffi::{OsStr, OsString};
 use io::{self, ErrorKind};
-use num::Zero;
 use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 use time::Duration;
@@ -68,6 +67,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
     match errno as c::DWORD {
         c::ERROR_ACCESS_DENIED => return ErrorKind::PermissionDenied,
         c::ERROR_ALREADY_EXISTS => return ErrorKind::AlreadyExists,
+        c::ERROR_FILE_EXISTS => return ErrorKind::AlreadyExists,
         c::ERROR_BROKEN_PIPE => return ErrorKind::BrokenPipe,
         c::ERROR_FILE_NOT_FOUND => return ErrorKind::NotFound,
         c::ERROR_PATH_NOT_FOUND => return ErrorKind::NotFound,
@@ -177,8 +177,22 @@ pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
     }
 }
 
-fn cvt<I: PartialEq + Zero>(i: I) -> io::Result<I> {
-    if i == I::zero() {
+trait IsZero {
+    fn is_zero(&self) -> bool;
+}
+
+macro_rules! impl_is_zero {
+    ($($t:ident)*) => ($(impl IsZero for $t {
+        fn is_zero(&self) -> bool {
+            *self == 0
+        }
+    })*)
+}
+
+impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
+
+fn cvt<I: IsZero>(i: I) -> io::Result<I> {
+    if i.is_zero() {
         Err(io::Error::last_os_error())
     } else {
         Ok(i)
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
index b770156582d..8762b34e3da 100644
--- a/src/libstd/sys/windows/mutex.rs
+++ b/src/libstd/sys/windows/mutex.rs
@@ -64,6 +64,8 @@ impl Mutex {
             held: UnsafeCell::new(false),
         }
     }
+    #[inline]
+    pub unsafe fn init(&mut self) {}
     pub unsafe fn lock(&self) {
         match kind() {
             Kind::SRWLock => c::AcquireSRWLockExclusive(raw(self)),
diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs
index b05dcf42a33..71e164f012f 100644
--- a/src/libstd/sys/windows/net.rs
+++ b/src/libstd/sys/windows/net.rs
@@ -17,8 +17,6 @@ use io::{self, Read};
 use libc::{c_int, c_void, c_ulong};
 use mem;
 use net::{SocketAddr, Shutdown};
-use num::One;
-use ops::Neg;
 use ptr;
 use sync::Once;
 use sys::c;
@@ -60,11 +58,26 @@ fn last_error() -> io::Error {
     io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
 }
 
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
 /// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
 /// and if so, returns the last error from the Windows socket interface. This
 /// function must be called before another call to the socket API is made.
-pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
-    if t == -T::one() {
+pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
+    if t.is_minus_one() {
         Err(last_error())
     } else {
         Ok(t)
@@ -82,7 +95,8 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
 
 /// Just to provide the same interface as sys/unix/net.rs
 pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
-    where T: One + PartialEq + Neg<Output=T>, F: FnMut() -> T
+    where T: IsMinusOne,
+          F: FnMut() -> T
 {
     cvt(f())
 }
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 32ca32e76cb..0cea7f81e36 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -278,23 +278,30 @@ pub struct Args {
     cur: *mut *mut u16,
 }
 
+unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString {
+    let mut len = 0;
+    while *ptr.offset(len) != 0 { len += 1; }
+
+    // Push it onto the list.
+    let ptr = ptr as *const u16;
+    let buf = slice::from_raw_parts(ptr, len as usize);
+    OsStringExt::from_wide(buf)
+}
+
 impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> {
-        self.range.next().map(|i| unsafe {
-            let ptr = *self.cur.offset(i);
-            let mut len = 0;
-            while *ptr.offset(len) != 0 { len += 1; }
-
-            // Push it onto the list.
-            let ptr = ptr as *const u16;
-            let buf = slice::from_raw_parts(ptr, len as usize);
-            OsStringExt::from_wide(buf)
-        })
+        self.range.next().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } )
     }
     fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
 }
 
+impl DoubleEndedIterator for Args {
+    fn next_back(&mut self) -> Option<OsString> {
+        self.range.next_back().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } )
+    }
+}
+
 impl ExactSizeIterator for Args {
     fn len(&self) -> usize { self.range.len() }
 }
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index 8631a63d653..6e9c67051a6 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -12,9 +12,10 @@ use prelude::v1::*;
 use os::windows::prelude::*;
 
 use ffi::OsStr;
-use path::Path;
 use io;
 use mem;
+use path::Path;
+use ptr;
 use rand::{self, Rng};
 use slice;
 use sys::c;
@@ -66,7 +67,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
                                              4096,
                                              4096,
                                              0,
-                                             0 as *mut _);
+                                             ptr::null_mut());
 
             // We pass the FILE_FLAG_FIRST_PIPE_INSTANCE flag above, and we're
             // also just doing a best effort at selecting a unique name. If
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index f4957297581..3ca75cf3643 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -24,7 +24,7 @@ use mem;
 use os::windows::ffi::OsStrExt;
 use path::Path;
 use ptr;
-use sync::StaticMutex;
+use sys::mutex::Mutex;
 use sys::c;
 use sys::fs::{OpenOptions, File};
 use sys::handle::Handle;
@@ -75,6 +75,10 @@ pub struct StdioPipes {
     pub stderr: Option<AnonPipe>,
 }
 
+struct DropGuard<'a> {
+    lock: &'a Mutex,
+}
+
 impl Command {
     pub fn new(program: &OsStr) -> Command {
         Command {
@@ -173,8 +177,8 @@ impl Command {
         //
         // For more information, msdn also has an article about this race:
         // http://support.microsoft.com/kb/315939
-        static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
-        let _lock = CREATE_PROCESS_LOCK.lock();
+        static CREATE_PROCESS_LOCK: Mutex = Mutex::new();
+        let _guard = DropGuard::new(&CREATE_PROCESS_LOCK);
 
         let mut pipes = StdioPipes {
             stdin: None,
@@ -224,6 +228,23 @@ impl fmt::Debug for Command {
     }
 }
 
+impl<'a> DropGuard<'a> {
+    fn new(lock: &'a Mutex) -> DropGuard<'a> {
+        unsafe {
+            lock.lock();
+            DropGuard { lock: lock }
+        }
+    }
+}
+
+impl<'a> Drop for DropGuard<'a> {
+    fn drop(&mut self) {
+        unsafe {
+            self.lock.unlock();
+        }
+    }
+}
+
 impl Stdio {
     fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>)
                  -> io::Result<Handle> {
@@ -337,6 +358,12 @@ impl ExitStatus {
     }
 }
 
+impl From<c::DWORD> for ExitStatus {
+    fn from(u: c::DWORD) -> ExitStatus {
+        ExitStatus(u)
+    }
+}
+
 impl fmt::Display for ExitStatus {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "exit code: {}", self.0)
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 6b54ec8afca..152b9771086 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -100,18 +100,52 @@ pub struct LocalKey<T: 'static> {
 
 /// Declare a new thread local storage key of type `std::thread::LocalKey`.
 ///
+/// # Syntax
+///
+/// The macro wraps any number of static declarations and makes them thread local.
+/// Each static may be public or private, and attributes are allowed. Example:
+///
+/// ```
+/// use std::cell::RefCell;
+/// thread_local! {
+///     pub static FOO: RefCell<u32> = RefCell::new(1);
+///
+///     #[allow(unused)]
+///     static BAR: RefCell<f32> = RefCell::new(1.0);
+/// }
+/// # fn main() {}
+/// ```
+///
 /// See [LocalKey documentation](thread/struct.LocalKey.html) for more
 /// information.
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable]
 macro_rules! thread_local {
-    (static $name:ident: $t:ty = $init:expr) => (
-        static $name: $crate::thread::LocalKey<$t> =
+    // rule 0: empty (base case for the recursion)
+    () => {};
+
+    // rule 1: process multiple declarations where the first one is private
+    ($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
+        thread_local!($(#[$attr])* static $name: $t = $init); // go to rule 2
+        thread_local!($($rest)*);
+    );
+
+    // rule 2: handle a single private declaration
+    ($(#[$attr:meta])* static $name:ident: $t:ty = $init:expr) => (
+        $(#[$attr])* static $name: $crate::thread::LocalKey<$t> =
             __thread_local_inner!($t, $init);
     );
-    (pub static $name:ident: $t:ty = $init:expr) => (
-        pub static $name: $crate::thread::LocalKey<$t> =
+
+    // rule 3: handle multiple declarations where the first one is public
+    ($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr; $($rest:tt)*) => (
+        thread_local!($(#[$attr])* pub static $name: $t = $init); // go to rule 4
+        thread_local!($($rest)*);
+    );
+
+    // rule 4: handle a single public declaration
+    ($(#[$attr:meta])* pub static $name:ident: $t:ty = $init:expr) => (
+        $(#[$attr])* pub static $name: $crate::thread::LocalKey<$t> =
             __thread_local_inner!($t, $init);
     );
 }
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index b3549dc1264..e9736fea7b3 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -13,7 +13,8 @@
 //! ## The threading model
 //!
 //! An executing Rust program consists of a collection of native OS threads,
-//! each with their own stack and local state.
+//! each with their own stack and local state. Threads can be named, and
+//! provide some built-in support for low-level synchronization.
 //!
 //! Communication between threads can be done through
 //! [channels](../../std/sync/mpsc/index.html), Rust's message-passing
@@ -37,20 +38,6 @@
 //! convenient facilities for automatically waiting for the termination of a
 //! child thread (i.e., join).
 //!
-//! ## The `Thread` type
-//!
-//! Threads are represented via the `Thread` type, which you can
-//! get in one of two ways:
-//!
-//! * By spawning a new thread, e.g. using the `thread::spawn` function.
-//! * By requesting the current thread, using the `thread::current` function.
-//!
-//! Threads can be named, and provide some built-in support for low-level
-//! synchronization (described below).
-//!
-//! The `thread::current()` function is available even for threads not spawned
-//! by the APIs of this module.
-//!
 //! ## Spawning a thread
 //!
 //! A new thread can be spawned using the `thread::spawn` function:
@@ -99,10 +86,24 @@
 //! });
 //! ```
 //!
+//! ## The `Thread` type
+//!
+//! Threads are represented via the `Thread` type, which you can get in one of
+//! two ways:
+//!
+//! * By spawning a new thread, e.g. using the `thread::spawn` function, and
+//!   calling `thread()` on the `JoinHandle`.
+//! * By requesting the current thread, using the `thread::current` function.
+//!
+//! The `thread::current()` function is available even for threads not spawned
+//! by the APIs of this module.
+//!
 //! ## Blocking support: park and unpark
 //!
 //! Every thread is equipped with some basic low-level blocking support, via the
-//! `park` and `unpark` functions.
+//! `thread::park()` function and `thread::Thread::unpark()` method. `park()`
+//! blocks the current thread, which can then be resumed from another thread by
+//! calling the `unpark()` method on the blocked thread's handle.
 //!
 //! Conceptually, each `Thread` handle has an associated token, which is
 //! initially not present:
@@ -164,14 +165,15 @@ use prelude::v1::*;
 
 use any::Any;
 use cell::UnsafeCell;
+use ffi::{CStr, CString};
 use fmt;
 use io;
+use panic;
+use panicking;
 use str;
-use ffi::{CStr, CString};
 use sync::{Mutex, Condvar, Arc};
 use sys::thread as imp;
 use sys_common::thread_info;
-use sys_common::unwind;
 use sys_common::util;
 use sys_common::{AsInner, IntoInner};
 use time::Duration;
@@ -181,25 +183,15 @@ use time::Duration;
 ////////////////////////////////////////////////////////////////////////////////
 
 #[macro_use] mod local;
-#[macro_use] mod scoped_tls;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::local::{LocalKey, LocalKeyState};
 
-#[unstable(feature = "scoped_tls",
-           reason = "scoped TLS has yet to have wide enough use to fully \
-                     consider stabilizing its interface",
-           issue = "27715")]
-#[allow(deprecated)]
-pub use self::scoped_tls::ScopedKey;
-
 #[unstable(feature = "libstd_thread_internals", issue = "0")]
 #[cfg(target_thread_local)]
 #[doc(hidden)] pub use self::local::elf::Key as __ElfLocalKeyInner;
 #[unstable(feature = "libstd_thread_internals", issue = "0")]
 #[doc(hidden)] pub use self::local::os::Key as __OsLocalKeyInner;
-#[unstable(feature = "libstd_thread_internals", issue = "0")]
-#[doc(hidden)] pub use self::scoped_tls::__KeyInner as __ScopedKeyInner;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Builder
@@ -228,6 +220,21 @@ impl Builder {
 
     /// Names the thread-to-be. Currently the name is used for identification
     /// only in panic messages.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::thread;
+    ///
+    /// let builder = thread::Builder::new()
+    ///     .name("foo".into());
+    ///
+    /// let handler = builder.spawn(|| {
+    ///     assert_eq!(thread::current().name(), Some("foo"))
+    /// }).unwrap();
+    ///
+    /// handler.join().unwrap();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn name(mut self, name: String) -> Builder {
         self.name = Some(name);
@@ -274,14 +281,8 @@ impl Builder {
             }
             unsafe {
                 thread_info::set(imp::guard::current(), their_thread);
-                let mut output = None;
-                let try_result = {
-                    let ptr = &mut output;
-                    unwind::try(move || *ptr = Some(f()))
-                };
-                *their_packet.get() = Some(try_result.map(|()| {
-                    output.unwrap()
-                }));
+                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
+                *their_packet.get() = Some(try_result);
             }
         };
 
@@ -335,10 +336,39 @@ pub fn yield_now() {
 }
 
 /// Determines whether the current thread is unwinding because of panic.
+///
+/// # Examples
+///
+/// ```rust,should_panic
+/// use std::thread;
+///
+/// struct SomeStruct;
+///
+/// impl Drop for SomeStruct {
+///     fn drop(&mut self) {
+///         if thread::panicking() {
+///             println!("dropped while unwinding");
+///         } else {
+///             println!("dropped while not unwinding");
+///         }
+///     }
+/// }
+///
+/// {
+///     print!("a: ");
+///     let a = SomeStruct;
+/// }
+///
+/// {
+///     print!("b: ");
+///     let b = SomeStruct;
+///     panic!()
+/// }
+/// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn panicking() -> bool {
-    unwind::panicking()
+    panicking::panicking()
 }
 
 /// Puts the current thread to sleep for the specified amount of time.
@@ -364,6 +394,19 @@ pub fn sleep_ms(ms: u32) {
 /// signal being received or a spurious wakeup. Platforms which do not support
 /// nanosecond precision for sleeping will have `dur` rounded up to the nearest
 /// granularity of time they can sleep for.
+///
+/// # Examples
+///
+/// ```rust,no_run
+/// use std::{thread, time};
+///
+/// let ten_millis = time::Duration::from_millis(10);
+/// let now = time::Instant::now();
+///
+/// thread::sleep(ten_millis);
+///
+/// assert!(now.elapsed() >= ten_millis);
+/// ```
 #[stable(feature = "thread_sleep", since = "1.4.0")]
 pub fn sleep(dur: Duration) {
     imp::Thread::sleep(dur)
@@ -408,10 +451,10 @@ pub fn park() {
 /// the specified duration has been reached (may wake spuriously).
 ///
 /// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than *ms*. This method
+/// thread will be blocked for roughly no longer than `ms`. This method
 /// should not be used for precise timing due to anomalies such as
 /// preemption or platform differences that may not cause the maximum
-/// amount of time waited to be precisely *ms* long.
+/// amount of time waited to be precisely `ms` long.
 ///
 /// See the module doc for more detail.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -424,10 +467,10 @@ pub fn park_timeout_ms(ms: u32) {
 /// the specified duration has been reached (may wake spuriously).
 ///
 /// The semantics of this function are equivalent to `park()` except that the
-/// thread will be blocked for roughly no longer than *dur*. This method
+/// thread will be blocked for roughly no longer than `dur`. This method
 /// should not be used for precise timing due to anomalies such as
 /// preemption or platform differences that may not cause the maximum
-/// amount of time waited to be precisely *dur* long.
+/// amount of time waited to be precisely `dur` long.
 ///
 /// See the module doc for more detail.
 ///
@@ -467,9 +510,9 @@ pub struct Thread {
 impl Thread {
     // Used only internally to construct a thread object without spawning
     fn new(name: Option<String>) -> Thread {
-        let cname = name.map(|n| CString::new(n).unwrap_or_else(|_| {
-            panic!("thread name may not contain interior null bytes")
-        }));
+        let cname = name.map(|n| {
+            CString::new(n).expect("thread name may not contain interior null bytes")
+        });
         Thread {
             inner: Arc::new(Inner {
                 name: cname,
@@ -492,6 +535,37 @@ impl Thread {
     }
 
     /// Gets the thread's name.
+    ///
+    /// # Examples
+    ///
+    /// Threads by default have no name specified:
+    ///
+    /// ```
+    /// use std::thread;
+    ///
+    /// let builder = thread::Builder::new();
+    ///
+    /// let handler = builder.spawn(|| {
+    ///     assert!(thread::current().name().is_none());
+    /// }).unwrap();
+    ///
+    /// handler.join().unwrap();
+    /// ```
+    ///
+    /// Thread with a specified name:
+    ///
+    /// ```
+    /// use std::thread;
+    ///
+    /// let builder = thread::Builder::new()
+    ///     .name("foo".into());
+    ///
+    /// let handler = builder.spawn(|| {
+    ///     assert_eq!(thread::current().name(), Some("foo"))
+    /// }).unwrap();
+    ///
+    /// handler.join().unwrap();
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn name(&self) -> Option<&str> {
         self.cname().map(|s| unsafe { str::from_utf8_unchecked(s.to_bytes()) } )
@@ -564,6 +638,36 @@ impl<T> JoinInner<T> {
 /// Due to platform restrictions, it is not possible to `Clone` this
 /// handle: the ability to join a child thread is a uniquely-owned
 /// permission.
+///
+/// This `struct` is created by the [`thread::spawn`] function and the
+/// [`thread::Builder::spawn`] method.
+///
+/// # Examples
+///
+/// Creation from [`thread::spawn`]:
+///
+/// ```rust
+/// use std::thread;
+///
+/// let join_handle: thread::JoinHandle<_> = thread::spawn(|| {
+///     // some work here
+/// });
+/// ```
+///
+/// Creation from [`thread::Builder::spawn`]:
+///
+/// ```rust
+/// use std::thread;
+///
+/// let builder = thread::Builder::new();
+///
+/// let join_handle: thread::JoinHandle<_> = builder.spawn(|| {
+///     // some work here
+/// }).unwrap();
+/// ```
+///
+/// [`thread::spawn`]: fn.spawn.html
+/// [`thread::Builder::spawn`]: struct.Builder.html#method.spawn
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinHandle<T>(JoinInner<T>);
 
diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs
deleted file mode 100644
index dea58d016e4..00000000000
--- a/src/libstd/thread/scoped_tls.rs
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2014-2015 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.
-
-//! Scoped thread-local storage
-//!
-//! This module provides the ability to generate *scoped* thread-local
-//! variables. In this sense, scoped indicates that thread local storage
-//! actually stores a reference to a value, and this reference is only placed
-//! in storage for a scoped amount of time.
-//!
-//! There are no restrictions on what types can be placed into a scoped
-//! variable, but all scoped variables are initialized to the equivalent of
-//! null. Scoped thread local storage is useful when a value is present for a known
-//! period of time and it is not required to relinquish ownership of the
-//! contents.
-//!
-//! # Examples
-//!
-//! ```
-//! #![feature(scoped_tls)]
-//!
-//! scoped_thread_local!(static FOO: u32);
-//!
-//! // Initially each scoped slot is empty.
-//! assert!(!FOO.is_set());
-//!
-//! // When inserting a value, the value is only in place for the duration
-//! // of the closure specified.
-//! FOO.set(&1, || {
-//!     FOO.with(|slot| {
-//!         assert_eq!(*slot, 1);
-//!     });
-//! });
-//! ```
-
-#![unstable(feature = "thread_local_internals", issue = "0")]
-#![allow(deprecated)]
-
-#[doc(hidden)]
-pub use self::imp::KeyInner as __KeyInner;
-
-/// Type representing a thread local storage key corresponding to a reference
-/// to the type parameter `T`.
-///
-/// Keys are statically allocated and can contain a reference to an instance of
-/// type `T` scoped to a particular lifetime. Keys provides two methods, `set`
-/// and `with`, both of which currently use closures to control the scope of
-/// their contents.
-#[unstable(feature = "scoped_tls",
-           reason = "scoped TLS has yet to have wide enough use to fully consider \
-                     stabilizing its interface",
-           issue = "27715")]
-#[rustc_deprecated(since = "1.8.0",
-                   reason = "hasn't proven itself over LocalKey")]
-pub struct ScopedKey<T:'static> { inner: fn() -> &'static imp::KeyInner<T> }
-
-/// Declare a new scoped thread local storage key.
-///
-/// This macro declares a `static` item on which methods are used to get and
-/// set the value stored within.
-///
-/// See [ScopedKey documentation](thread/struct.ScopedKey.html) for more
-/// information.
-#[unstable(feature = "thread_local_internals",
-           reason = "should not be necessary",
-           issue = "0")]
-#[rustc_deprecated(since = "1.8.0",
-                   reason = "hasn't proven itself over LocalKey")]
-#[macro_export]
-#[allow_internal_unstable]
-macro_rules! scoped_thread_local {
-    (static $name:ident: $t:ty) => (
-        static $name: $crate::thread::ScopedKey<$t> =
-            __scoped_thread_local_inner!($t);
-    );
-    (pub static $name:ident: $t:ty) => (
-        pub static $name: $crate::thread::ScopedKey<$t> =
-            __scoped_thread_local_inner!($t);
-    );
-}
-
-#[doc(hidden)]
-#[unstable(feature = "thread_local_internals",
-           reason = "should not be necessary",
-           issue = "0")]
-#[rustc_deprecated(since = "1.8.0",
-                   reason = "hasn't proven itself over LocalKey")]
-#[macro_export]
-#[allow_internal_unstable]
-macro_rules! __scoped_thread_local_inner {
-    ($t:ty) => {{
-        #[cfg_attr(target_thread_local, thread_local)]
-        static _KEY: $crate::thread::__ScopedKeyInner<$t> =
-            $crate::thread::__ScopedKeyInner::new();
-        fn _getit() -> &'static $crate::thread::__ScopedKeyInner<$t> { &_KEY }
-        $crate::thread::ScopedKey::new(_getit)
-    }}
-}
-
-#[unstable(feature = "scoped_tls",
-           reason = "scoped TLS has yet to have wide enough use to fully consider \
-                     stabilizing its interface",
-           issue = "27715")]
-#[rustc_deprecated(since = "1.8.0",
-                   reason = "hasn't proven itself over LocalKey")]
-impl<T> ScopedKey<T> {
-    #[doc(hidden)]
-    pub const fn new(inner: fn() -> &'static imp::KeyInner<T>) -> ScopedKey<T> {
-        ScopedKey { inner: inner }
-    }
-
-    /// Inserts a value into this scoped thread local storage slot for a
-    /// duration of a closure.
-    ///
-    /// While `cb` is running, the value `t` will be returned by `get` unless
-    /// this function is called recursively inside of `cb`.
-    ///
-    /// Upon return, this function will restore the previous value, if any
-    /// was available.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(scoped_tls)]
-    ///
-    /// scoped_thread_local!(static FOO: u32);
-    ///
-    /// FOO.set(&100, || {
-    ///     let val = FOO.with(|v| *v);
-    ///     assert_eq!(val, 100);
-    ///
-    ///     // set can be called recursively
-    ///     FOO.set(&101, || {
-    ///         // ...
-    ///     });
-    ///
-    ///     // Recursive calls restore the previous value.
-    ///     let val = FOO.with(|v| *v);
-    ///     assert_eq!(val, 100);
-    /// });
-    /// ```
-    pub fn set<R, F>(&'static self, t: &T, cb: F) -> R where
-        F: FnOnce() -> R,
-    {
-        struct Reset<'a, T: 'a> {
-            key: &'a imp::KeyInner<T>,
-            val: *mut T,
-        }
-                impl<'a, T> Drop for Reset<'a, T> {
-            fn drop(&mut self) {
-                unsafe { self.key.set(self.val) }
-            }
-        }
-
-        let inner = (self.inner)();
-        let prev = unsafe {
-            let prev = inner.get();
-            inner.set(t as *const T as *mut T);
-            prev
-        };
-
-        let _reset = Reset { key: inner, val: prev };
-        cb()
-    }
-
-    /// Gets a value out of this scoped variable.
-    ///
-    /// This function takes a closure which receives the value of this
-    /// variable.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if `set` has not previously been called.
-    ///
-    /// # Examples
-    ///
-    /// ```no_run
-    /// #![feature(scoped_tls)]
-    ///
-    /// scoped_thread_local!(static FOO: u32);
-    ///
-    /// FOO.with(|slot| {
-    ///     // work with `slot`
-    /// });
-    /// ```
-    pub fn with<R, F>(&'static self, cb: F) -> R where
-        F: FnOnce(&T) -> R
-    {
-        unsafe {
-            let ptr = (self.inner)().get();
-            assert!(!ptr.is_null(), "cannot access a scoped thread local \
-                                     variable without calling `set` first");
-            cb(&*ptr)
-        }
-    }
-
-    /// Test whether this TLS key has been `set` for the current thread.
-    pub fn is_set(&'static self) -> bool {
-        unsafe { !(self.inner)().get().is_null() }
-    }
-}
-
-#[cfg(target_thread_local)]
-#[doc(hidden)]
-mod imp {
-    use cell::Cell;
-    use ptr;
-
-    pub struct KeyInner<T> { inner: Cell<*mut T> }
-
-    unsafe impl<T> ::marker::Sync for KeyInner<T> { }
-
-    impl<T> KeyInner<T> {
-        pub const fn new() -> KeyInner<T> {
-            KeyInner { inner: Cell::new(ptr::null_mut()) }
-        }
-        pub unsafe fn set(&self, ptr: *mut T) { self.inner.set(ptr); }
-        pub unsafe fn get(&self) -> *mut T { self.inner.get() }
-    }
-}
-
-#[cfg(not(target_thread_local))]
-#[doc(hidden)]
-mod imp {
-    use cell::Cell;
-    use marker;
-    use sys_common::thread_local::StaticKey as OsStaticKey;
-
-    pub struct KeyInner<T> {
-        pub inner: OsStaticKey,
-        pub marker: marker::PhantomData<Cell<T>>,
-    }
-
-    unsafe impl<T> marker::Sync for KeyInner<T> { }
-
-    impl<T> KeyInner<T> {
-        pub const fn new() -> KeyInner<T> {
-            KeyInner {
-                inner: OsStaticKey::new(None),
-                marker: marker::PhantomData
-            }
-        }
-        pub unsafe fn set(&self, ptr: *mut T) { self.inner.set(ptr as *mut _) }
-        pub unsafe fn get(&self) -> *mut T { self.inner.get() as *mut _ }
-    }
-}
-
-
-#[cfg(test)]
-mod tests {
-    use cell::Cell;
-
-    scoped_thread_local!(static FOO: u32);
-
-    #[test]
-    fn smoke() {
-        scoped_thread_local!(static BAR: u32);
-
-        assert!(!BAR.is_set());
-        BAR.set(&1, || {
-            assert!(BAR.is_set());
-            BAR.with(|slot| {
-                assert_eq!(*slot, 1);
-            });
-        });
-        assert!(!BAR.is_set());
-    }
-
-    #[test]
-    fn cell_allowed() {
-        scoped_thread_local!(static BAR: Cell<u32>);
-
-        BAR.set(&Cell::new(1), || {
-            BAR.with(|slot| {
-                assert_eq!(slot.get(), 1);
-            });
-        });
-    }
-
-    #[test]
-    fn scope_item_allowed() {
-        assert!(!FOO.is_set());
-        FOO.set(&1, || {
-            assert!(FOO.is_set());
-            FOO.with(|slot| {
-                assert_eq!(*slot, 1);
-            });
-        });
-        assert!(!FOO.is_set());
-    }
-}
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 8a50f07e6d8..79bbe5e7daa 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -51,10 +51,16 @@ impl Duration {
     ///
     /// If the nanoseconds is greater than 1 billion (the number of nanoseconds
     /// in a second), then it will carry over into the seconds provided.
+    ///
+    /// # Panics
+    ///
+    /// This constructor will panic if the carry from the nanoseconds overflows
+    /// the seconds counter.
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn new(secs: u64, nanos: u32) -> Duration {
-        let secs = secs + (nanos / NANOS_PER_SEC) as u64;
+        let secs = secs.checked_add((nanos / NANOS_PER_SEC) as u64)
+            .expect("overflow in Duration::new");
         let nanos = nanos % NANOS_PER_SEC;
         Duration { secs: secs, nanos: nanos }
     }
diff --git a/src/libstd/time/mod.rs b/src/libstd/time/mod.rs
index bc50b0d3a70..0e1508a1c4c 100644
--- a/src/libstd/time/mod.rs
+++ b/src/libstd/time/mod.rs
@@ -76,7 +76,7 @@ pub struct Instant(time::Instant);
 /// Distinct from the `Instant` type, this time measurement **is not
 /// monotonic**. This means that you can save a file to the file system, then
 /// save another file to the file system, **and the second file has a
-/// `SystemTime` measurement earlier than the second**. In other words, an
+/// `SystemTime` measurement earlier than the first**. In other words, an
 /// operation that happens after another operation in real time may have an
 /// earlier `SystemTime`!
 ///
@@ -143,13 +143,6 @@ impl Instant {
         self.0.sub_instant(&earlier.0)
     }
 
-    /// Deprecated, renamed to `duration_since`
-    #[unstable(feature = "time2_old", issue = "29866")]
-    #[rustc_deprecated(since = "1.8.0", reason = "renamed to duration_since")]
-    pub fn duration_from_earlier(&self, earlier: Instant) -> Duration {
-        self.0.sub_instant(&earlier.0)
-    }
-
     /// Returns the amount of time elapsed since this instant was created.
     ///
     /// # Panics
@@ -235,14 +228,6 @@ impl SystemTime {
         self.0.sub_time(&earlier.0).map_err(SystemTimeError)
     }
 
-    /// Deprecated, renamed to `duration_since`
-    #[unstable(feature = "time2_old", issue = "29866")]
-    #[rustc_deprecated(since = "1.8.0", reason = "renamed to duration_since")]
-    pub fn duration_from_earlier(&self, earlier: SystemTime)
-                                 -> Result<Duration, SystemTimeError> {
-        self.0.sub_time(&earlier.0).map_err(SystemTimeError)
-    }
-
     /// Returns the amount of time elapsed since this system time was created.
     ///
     /// This function may fail as the underlying system clock is susceptible to