about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorDjzin <djzin@users.noreply.github.com>2017-05-27 14:31:47 +0100
committerDjzin <djzin@users.noreply.github.com>2017-05-27 14:31:47 +0100
commit74751358e625878306aa193fed788e79aa53d4fa (patch)
tree1ba9b336d1ddb45d9f688d69f5bd4ede028db622 /src/libstd
parentc6307a2fa55c3d62c06b85b349257a8194093442 (diff)
parent3e7908f616745573a11ad7dfad245f12be0069da (diff)
downloadrust-74751358e625878306aa193fed788e79aa53d4fa.tar.gz
rust-74751358e625878306aa193fed788e79aa53d4fa.zip
Merge remote-tracking branch 'upstream/master' into fast-swap
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/Cargo.toml4
-rw-r--r--src/libstd/ascii.rs95
-rw-r--r--src/libstd/build.rs5
-rw-r--r--src/libstd/collections/hash/map.rs315
-rw-r--r--src/libstd/collections/hash/set.rs171
-rw-r--r--src/libstd/collections/hash/table.rs393
-rw-r--r--src/libstd/collections/mod.rs60
-rw-r--r--src/libstd/env.rs70
-rw-r--r--src/libstd/error.rs11
-rw-r--r--src/libstd/f32.rs299
-rw-r--r--src/libstd/f64.rs257
-rw-r--r--src/libstd/ffi/c_str.rs150
-rw-r--r--src/libstd/ffi/os_str.rs120
-rw-r--r--src/libstd/fs.rs93
-rw-r--r--src/libstd/io/buffered.rs17
-rw-r--r--src/libstd/io/cursor.rs4
-rw-r--r--src/libstd/io/error.rs4
-rw-r--r--src/libstd/io/mod.rs399
-rw-r--r--src/libstd/io/stdio.rs63
-rw-r--r--src/libstd/io/util.rs6
-rw-r--r--src/libstd/lib.rs36
-rw-r--r--src/libstd/macros.rs47
-rw-r--r--src/libstd/net/addr.rs198
-rw-r--r--src/libstd/net/ip.rs267
-rw-r--r--src/libstd/net/mod.rs51
-rw-r--r--src/libstd/net/parser.rs14
-rw-r--r--src/libstd/net/tcp.rs121
-rw-r--r--src/libstd/net/udp.rs56
-rw-r--r--src/libstd/num.rs3
-rw-r--r--src/libstd/os/android/raw.rs63
-rw-r--r--src/libstd/os/linux/fs.rs19
-rw-r--r--src/libstd/os/macos/mod.rs2
-rw-r--r--src/libstd/os/macos/raw.rs2
-rw-r--r--src/libstd/os/raw.rs10
-rw-r--r--src/libstd/panicking.rs8
-rw-r--r--src/libstd/path.rs500
-rw-r--r--src/libstd/prelude/mod.rs16
-rw-r--r--src/libstd/primitive_docs.rs29
-rw-r--r--src/libstd/process.rs125
-rw-r--r--src/libstd/rand/mod.rs4
-rw-r--r--src/libstd/rt.rs14
-rw-r--r--src/libstd/sync/barrier.rs9
-rw-r--r--src/libstd/sync/condvar.rs20
-rw-r--r--src/libstd/sync/mpsc/mod.rs591
-rw-r--r--src/libstd/sync/mpsc/mpsc_queue.rs35
-rw-r--r--src/libstd/sync/mpsc/spsc_queue.rs39
-rw-r--r--src/libstd/sync/mutex.rs34
-rw-r--r--src/libstd/sync/once.rs37
-rw-r--r--src/libstd/sync/rwlock.rs14
-rw-r--r--src/libstd/sys/redox/fast_thread_local.rs13
-rw-r--r--src/libstd/sys/redox/os_str.rs6
-rw-r--r--src/libstd/sys/redox/process.rs23
-rw-r--r--src/libstd/sys/redox/syscall/call.rs5
-rw-r--r--src/libstd/sys/redox/syscall/number.rs1
-rw-r--r--src/libstd/sys/redox/thread_local.rs5
-rw-r--r--src/libstd/sys/unix/backtrace/mod.rs8
-rw-r--r--src/libstd/sys/unix/ext/net.rs40
-rw-r--r--src/libstd/sys/unix/fast_thread_local.rs14
-rw-r--r--src/libstd/sys/unix/fd.rs2
-rw-r--r--src/libstd/sys/unix/fs.rs4
-rw-r--r--src/libstd/sys/unix/mod.rs2
-rw-r--r--src/libstd/sys/unix/os.rs7
-rw-r--r--src/libstd/sys/unix/os_str.rs6
-rw-r--r--src/libstd/sys/unix/pipe.rs22
-rw-r--r--src/libstd/sys/unix/process/magenta.rs77
-rw-r--r--src/libstd/sys/unix/process/process_common.rs20
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs13
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs2
-rw-r--r--src/libstd/sys/unix/thread_local.rs5
-rw-r--r--src/libstd/sys/unix/time.rs2
-rw-r--r--src/libstd/sys/windows/c.rs11
-rw-r--r--src/libstd/sys/windows/ext/ffi.rs42
-rw-r--r--src/libstd/sys/windows/ext/fs.rs293
-rw-r--r--src/libstd/sys/windows/ext/mod.rs10
-rw-r--r--src/libstd/sys/windows/ext/process.rs1
-rw-r--r--src/libstd/sys/windows/os.rs38
-rw-r--r--src/libstd/sys/windows/os_str.rs6
-rw-r--r--src/libstd/sys/windows/process.rs9
-rw-r--r--src/libstd/sys/windows/stdio.rs92
-rw-r--r--src/libstd/sys/windows/thread_local.rs165
-rw-r--r--src/libstd/sys_common/backtrace.rs90
-rw-r--r--src/libstd/sys_common/net.rs23
-rw-r--r--src/libstd/sys_common/poison.rs4
-rw-r--r--src/libstd/sys_common/thread_info.rs7
-rw-r--r--src/libstd/sys_common/thread_local.rs37
-rw-r--r--src/libstd/sys_common/wtf8.rs7
-rw-r--r--src/libstd/thread/local.rs51
-rw-r--r--src/libstd/thread/mod.rs430
-rw-r--r--src/libstd/time/duration.rs29
89 files changed, 4349 insertions, 2173 deletions
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 46511452a72..717892be2ab 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -23,6 +23,10 @@ compiler_builtins = { path = "../libcompiler_builtins" }
 std_unicode = { path = "../libstd_unicode" }
 unwind = { path = "../libunwind" }
 
+[target.x86_64-apple-darwin.dependencies]
+rustc_asan = { path = "../librustc_asan" }
+rustc_tsan = { path = "../librustc_tsan" }
+
 [target.x86_64-unknown-linux-gnu.dependencies]
 rustc_asan = { path = "../librustc_asan" }
 rustc_lsan = { path = "../librustc_lsan" }
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index af21d6d906e..4e3781ecafa 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -9,15 +9,28 @@
 // except according to those terms.
 
 //! Operations on ASCII strings and characters.
+//!
+//! Most string operations in Rust act on UTF-8 strings. However, at times it
+//! makes more sense to only consider the ASCII character set for a specific
+//! operation.
+//!
+//! The [`AsciiExt`] trait provides methods that allow for character
+//! operations that only act on the ASCII subset and leave non-ASCII characters
+//! alone.
+//!
+//! The [`escape_default`] function provides an iterator over the bytes of an
+//! escaped version of the character given.
+//!
+//! [`AsciiExt`]: trait.AsciiExt.html
+//! [`escape_default`]: fn.escape_default.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use fmt;
-use mem;
 use ops::Range;
 use iter::FusedIterator;
 
-/// Extension methods for ASCII-subset only operations on string slices.
+/// Extension methods for ASCII-subset only operations.
 ///
 /// Be aware that operations on seemingly non-ASCII characters can sometimes
 /// have unexpected results. Consider this example:
@@ -53,20 +66,22 @@ pub trait AsciiExt {
     /// use std::ascii::AsciiExt;
     ///
     /// let ascii = 'a';
-    /// let utf8 = '❤';
+    /// let non_ascii = '❤';
+    /// let int_ascii = 97;
     ///
     /// assert!(ascii.is_ascii());
-    /// assert!(!utf8.is_ascii());
+    /// assert!(!non_ascii.is_ascii());
+    /// assert!(int_ascii.is_ascii());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn is_ascii(&self) -> bool;
 
-    /// Makes a copy of the string in ASCII upper case.
+    /// Makes a copy of the value in its ASCII upper case equivalent.
     ///
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To uppercase the string in-place, use [`make_ascii_uppercase`].
+    /// To uppercase the value in-place, use [`make_ascii_uppercase`].
     ///
     /// To uppercase ASCII characters in addition to non-ASCII characters, use
     /// [`str::to_uppercase`].
@@ -77,10 +92,12 @@ pub trait AsciiExt {
     /// use std::ascii::AsciiExt;
     ///
     /// let ascii = 'a';
-    /// let utf8 = '❤';
+    /// let non_ascii = '❤';
+    /// let int_ascii = 97;
     ///
     /// assert_eq!('A', ascii.to_ascii_uppercase());
-    /// assert_eq!('❤', utf8.to_ascii_uppercase());
+    /// assert_eq!('❤', non_ascii.to_ascii_uppercase());
+    /// assert_eq!(65, int_ascii.to_ascii_uppercase());
     /// ```
     ///
     /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase
@@ -88,12 +105,12 @@ pub trait AsciiExt {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_ascii_uppercase(&self) -> Self::Owned;
 
-    /// Makes a copy of the string in ASCII lower case.
+    /// Makes a copy of the value in its ASCII lower case equivalent.
     ///
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To lowercase the string in-place, use [`make_ascii_lowercase`].
+    /// To lowercase the value in-place, use [`make_ascii_lowercase`].
     ///
     /// To lowercase ASCII characters in addition to non-ASCII characters, use
     /// [`str::to_lowercase`].
@@ -104,10 +121,12 @@ pub trait AsciiExt {
     /// use std::ascii::AsciiExt;
     ///
     /// let ascii = 'A';
-    /// let utf8 = '❤';
+    /// let non_ascii = '❤';
+    /// let int_ascii = 65;
     ///
     /// assert_eq!('a', ascii.to_ascii_lowercase());
-    /// assert_eq!('❤', utf8.to_ascii_lowercase());
+    /// assert_eq!('❤', non_ascii.to_ascii_lowercase());
+    /// assert_eq!(97, int_ascii.to_ascii_lowercase());
     /// ```
     ///
     /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase
@@ -115,10 +134,10 @@ pub trait AsciiExt {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_ascii_lowercase(&self) -> Self::Owned;
 
-    /// Checks that two strings are an ASCII case-insensitive match.
+    /// Checks that two values are an ASCII case-insensitive match.
     ///
     /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
-    /// but without allocating and copying temporary strings.
+    /// but without allocating and copying temporaries.
     ///
     /// # Examples
     ///
@@ -142,7 +161,7 @@ pub trait AsciiExt {
     /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To return a new uppercased string without modifying the existing one, use
+    /// To return a new uppercased value without modifying the existing one, use
     /// [`to_ascii_uppercase`].
     ///
     /// # Examples
@@ -166,7 +185,7 @@ pub trait AsciiExt {
     /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
     /// but non-ASCII letters are unchanged.
     ///
-    /// To return a new lowercased string without modifying the existing one, use
+    /// To return a new lowercased value without modifying the existing one, use
     /// [`to_ascii_lowercase`].
     ///
     /// # Examples
@@ -579,12 +598,12 @@ impl AsciiExt for str {
     }
 
     fn make_ascii_uppercase(&mut self) {
-        let me: &mut [u8] = unsafe { mem::transmute(self) };
+        let me = unsafe { self.as_bytes_mut() };
         me.make_ascii_uppercase()
     }
 
     fn make_ascii_lowercase(&mut self) {
-        let me: &mut [u8] = unsafe { mem::transmute(self) };
+        let me = unsafe { self.as_bytes_mut() };
         me.make_ascii_lowercase()
     }
 
@@ -928,8 +947,12 @@ impl AsciiExt for char {
     }
 }
 
-/// An iterator over the escaped version of a byte, constructed via
-/// `std::ascii::escape_default`.
+/// An iterator over the escaped version of a byte.
+///
+/// This `struct` is created by the [`escape_default`] function. See its
+/// documentation for more.
+///
+/// [`escape_default`]: fn.escape_default.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct EscapeDefault {
     range: Range<usize>,
@@ -960,6 +983,38 @@ pub struct EscapeDefault {
 ///
 /// assert_eq!(b'\\', escaped.next().unwrap());
 /// assert_eq!(b't', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\r');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'r', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\n');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'n', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\'');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'\'', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'"');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'"', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\\');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'\\', escaped.next().unwrap());
+///
+/// let mut escaped = ascii::escape_default(b'\x9d');
+///
+/// assert_eq!(b'\\', escaped.next().unwrap());
+/// assert_eq!(b'x', escaped.next().unwrap());
+/// assert_eq!(b'9', escaped.next().unwrap());
+/// assert_eq!(b'd', escaped.next().unwrap());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn escape_default(c: u8) -> EscapeDefault {
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 9fb83ad7598..f84662c3f86 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -43,11 +43,16 @@ fn main() {
         println!("cargo:rustc-link-lib=pthread");
     } else if target.contains("apple-darwin") {
         println!("cargo:rustc-link-lib=System");
+
+        // res_init and friends require -lresolv on macOS/iOS.
+        // See #41582 and http://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
+        println!("cargo:rustc-link-lib=resolv");
     } else if target.contains("apple-ios") {
         println!("cargo:rustc-link-lib=System");
         println!("cargo:rustc-link-lib=objc");
         println!("cargo:rustc-link-lib=framework=Security");
         println!("cargo:rustc-link-lib=framework=Foundation");
+        println!("cargo:rustc-link-lib=resolv");
     } else if target.contains("windows") {
         println!("cargo:rustc-link-lib=advapi32");
         println!("cargo:rustc-link-lib=ws2_32");
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index f9b0ec479d7..8c4cbb66b45 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -19,8 +19,9 @@ use fmt::{self, Debug};
 use hash::{Hash, Hasher, BuildHasher, SipHasher13};
 use iter::{FromIterator, FusedIterator};
 use mem::{self, replace};
-use ops::{Deref, Index};
+use ops::{Deref, Index, InPlace, Place, Placer};
 use rand::{self, Rng};
+use ptr;
 
 use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash};
 use super::table::BucketState::{Empty, Full};
@@ -214,15 +215,14 @@ const DISPLACEMENT_THRESHOLD: usize = 128;
 // 1. Alfredo Viola (2005). Distributional analysis of Robin Hood linear probing
 //    hashing with buckets.
 
-/// A hash map implementation which uses linear probing with Robin Hood bucket
-/// stealing.
+/// A hash map implemented with linear probing and Robin Hood bucket stealing.
 ///
 /// By default, `HashMap` uses a hashing algorithm selected to provide
 /// resistance against HashDoS attacks. The algorithm is randomly seeded, and a
 /// reasonable best-effort is made to generate this seed from a high quality,
 /// secure source of randomness provided by the host without blocking the
-/// program. Because of this, the randomness of the seed is dependant on the
-/// quality of the system's random number generator at the time it is created.
+/// program. Because of this, the randomness of the seed depends on the output
+/// quality of the system's random number generator when the seed is created.
 /// In particular, seeds generated when the system's entropy pool is abnormally
 /// low such as during system boot may be of a lower quality.
 ///
@@ -234,9 +234,8 @@ const DISPLACEMENT_THRESHOLD: usize = 128;
 /// attacks such as HashDoS.
 ///
 /// The hashing algorithm can be replaced on a per-`HashMap` basis using the
-/// [`HashMap::default`], [`HashMap::with_hasher`], and
-/// [`HashMap::with_capacity_and_hasher`] methods. Many alternative algorithms
-/// are available on crates.io, such as the [`fnv`] crate.
+/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many
+/// alternative algorithms are available on crates.io, such as the [`fnv`] crate.
 ///
 /// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although
 /// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.
@@ -338,9 +337,9 @@ const DISPLACEMENT_THRESHOLD: usize = 128;
 /// [`PartialEq`]: ../../std/cmp/trait.PartialEq.html
 /// [`RefCell`]: ../../std/cell/struct.RefCell.html
 /// [`Cell`]: ../../std/cell/struct.Cell.html
-/// [`HashMap::default`]: #method.default
-/// [`HashMap::with_hasher`]: #method.with_hasher
-/// [`HashMap::with_capacity_and_hasher`]: #method.with_capacity_and_hasher
+/// [`default`]: #method.default
+/// [`with_hasher`]: #method.with_hasher
+/// [`with_capacity_and_hasher`]: #method.with_capacity_and_hasher
 /// [`fnv`]: https://crates.io/crates/fnv
 ///
 /// ```
@@ -372,7 +371,7 @@ const DISPLACEMENT_THRESHOLD: usize = 128;
 /// }
 /// ```
 ///
-/// A HashMap with fixed list of elements can be initialized from an array:
+/// A `HashMap` with fixed list of elements can be initialized from an array:
 ///
 /// ```
 /// use std::collections::HashMap;
@@ -471,7 +470,7 @@ fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>)
     }
 
     // Now we've done all our shifting. Return the value we grabbed earlier.
-    (retkey, retval, gap.into_bucket().into_table())
+    (retkey, retval, gap.into_table())
 }
 
 /// Perform robin hood bucket stealing at the given `bucket`. You must
@@ -483,15 +482,15 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
                                 mut hash: SafeHash,
                                 mut key: K,
                                 mut val: V)
-                                -> &'a mut V {
-    let start_index = bucket.index();
+                                -> FullBucketMut<'a, K, V> {
     let size = bucket.table().size();
-    // Save the *starting point*.
-    let mut bucket = bucket.stash();
+    let raw_capacity = bucket.table().capacity();
     // There can be at most `size - dib` buckets to displace, because
     // in the worst case, there are `size` elements and we already are
     // `displacement` buckets away from the initial one.
-    let idx_end = start_index + size - bucket.displacement();
+    let idx_end = (bucket.index() + size - bucket.displacement()) % raw_capacity;
+    // Save the *starting point*.
+    let mut bucket = bucket.stash();
 
     loop {
         let (old_hash, old_key, old_val) = bucket.replace(hash, key, val);
@@ -515,7 +514,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
                     // bucket, which is a FullBucket on top of a
                     // FullBucketMut, into just one FullBucketMut. The "table"
                     // refers to the inner FullBucketMut in this context.
-                    return bucket.into_table().into_mut_refs().1;
+                    return bucket.into_table();
                 }
                 Full(bucket) => bucket,
             };
@@ -567,11 +566,8 @@ impl<K, V, S> HashMap<K, V, S>
     // The caller should ensure that invariants by Robin Hood Hashing hold
     // and that there's space in the underlying table.
     fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) {
-        let raw_cap = self.raw_capacity();
         let mut buckets = Bucket::new(&mut self.table, hash);
-        // note that buckets.index() keeps increasing
-        // even if the pointer wraps back to the first bucket.
-        let limit_bucket = buckets.index() + raw_cap;
+        let start_index = buckets.index();
 
         loop {
             // We don't need to compare hashes for value swap.
@@ -584,7 +580,7 @@ impl<K, V, S> HashMap<K, V, S>
                 Full(b) => b.into_bucket(),
             };
             buckets.next();
-            debug_assert!(buckets.index() < limit_bucket);
+            debug_assert!(buckets.index() != start_index);
         }
     }
 }
@@ -656,12 +652,13 @@ impl<K, V, S> HashMap<K, V, S>
         }
     }
 
-    /// Creates an empty `HashMap` with the specified capacity, using `hasher`
+    /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
     /// to hash the keys.
     ///
     /// The hash map will be able to hold at least `capacity` elements without
     /// reallocating. If `capacity` is 0, the hash map will not allocate.
-    /// Warning: `hasher` is normally randomly generated, and
+    ///
+    /// Warning: `hash_builder` is normally randomly generated, and
     /// is designed to allow HashMaps to be resistant to attacks that
     /// cause many collisions and very poor performance. Setting it
     /// manually using this function can expose a DoS attack vector.
@@ -688,7 +685,9 @@ impl<K, V, S> HashMap<K, V, S>
         }
     }
 
-    /// Returns a reference to the map's hasher.
+    /// Returns a reference to the map's [`BuildHasher`].
+    ///
+    /// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
     #[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
     pub fn hasher(&self) -> &S {
         &self.hash_builder
@@ -851,7 +850,7 @@ impl<K, V, S> HashMap<K, V, S>
     }
 
     /// An iterator visiting all keys in arbitrary order.
-    /// Iterator element type is `&'a K`.
+    /// The iterator element type is `&'a K`.
     ///
     /// # Examples
     ///
@@ -873,7 +872,7 @@ impl<K, V, S> HashMap<K, V, S>
     }
 
     /// An iterator visiting all values in arbitrary order.
-    /// Iterator element type is `&'a V`.
+    /// The iterator element type is `&'a V`.
     ///
     /// # Examples
     ///
@@ -895,7 +894,7 @@ impl<K, V, S> HashMap<K, V, S>
     }
 
     /// An iterator visiting all values mutably in arbitrary order.
-    /// Iterator element type is `&'a mut V`.
+    /// The iterator element type is `&'a mut V`.
     ///
     /// # Examples
     ///
@@ -922,7 +921,7 @@ impl<K, V, S> HashMap<K, V, S>
     }
 
     /// An iterator visiting all key-value pairs in arbitrary order.
-    /// Iterator element type is `(&'a K, &'a V)`.
+    /// The iterator element type is `(&'a K, &'a V)`.
     ///
     /// # Examples
     ///
@@ -945,7 +944,7 @@ impl<K, V, S> HashMap<K, V, S>
 
     /// An iterator visiting all key-value pairs in arbitrary order,
     /// with mutable references to the values.
-    /// Iterator element type is `(&'a K, &'a mut V)`.
+    /// The iterator element type is `(&'a K, &'a mut V)`.
     ///
     /// # Examples
     ///
@@ -1232,35 +1231,35 @@ impl<K, V, S> HashMap<K, V, S>
     /// # Examples
     ///
     /// ```
-    /// #![feature(retain_hash_collection)]
     /// use std::collections::HashMap;
     ///
     /// let mut map: HashMap<isize, isize> = (0..8).map(|x|(x, x*10)).collect();
     /// map.retain(|&k, _| k % 2 == 0);
     /// assert_eq!(map.len(), 4);
     /// ```
-    #[unstable(feature = "retain_hash_collection", issue = "36648")]
+    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
     pub fn retain<F>(&mut self, mut f: F)
         where F: FnMut(&K, &mut V) -> bool
     {
-        if self.table.capacity() == 0 || self.table.size() == 0 {
+        if self.table.size() == 0 {
             return;
         }
+        let mut elems_left = self.table.size();
         let mut bucket = Bucket::head_bucket(&mut self.table);
         bucket.prev();
-        let tail = bucket.index();
-        loop {
+        let start_index = bucket.index();
+        while elems_left != 0 {
             bucket = match bucket.peek() {
                 Full(mut full) => {
+                    elems_left -= 1;
                     let should_remove = {
                         let (k, v) = full.read_mut();
                         !f(k, v)
                     };
                     if should_remove {
-                        let prev_idx = full.index();
                         let prev_raw = full.raw();
                         let (_, _, t) = pop_internal(full);
-                        Bucket::new_from(prev_raw, prev_idx, t)
+                        Bucket::new_from(prev_raw, t)
                     } else {
                         full.into_bucket()
                     }
@@ -1270,9 +1269,7 @@ impl<K, V, S> HashMap<K, V, S>
                 }
             };
             bucket.prev();  // reverse iteration
-            if bucket.index() == tail {
-                break;
-            }
+            debug_assert!(elems_left == 0 || bucket.index() != start_index);
         }
     }
 }
@@ -1336,7 +1333,13 @@ impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S>
     }
 }
 
-/// HashMap iterator.
+/// An iterator over the entries of a `HashMap`.
+///
+/// This `struct` is created by the [`iter`] method on [`HashMap`]. See its
+/// documentation for more.
+///
+/// [`iter`]: struct.HashMap.html#method.iter
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, K: 'a, V: 'a> {
     inner: table::Iter<'a, K, V>,
@@ -1359,19 +1362,37 @@ impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> {
     }
 }
 
-/// HashMap mutable values iterator.
+/// A mutable iterator over the entries of a `HashMap`.
+///
+/// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its
+/// documentation for more.
+///
+/// [`iter_mut`]: struct.HashMap.html#method.iter_mut
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, K: 'a, V: 'a> {
     inner: table::IterMut<'a, K, V>,
 }
 
-/// HashMap move iterator.
+/// An owning iterator over the entries of a `HashMap`.
+///
+/// This `struct` is created by the [`into_iter`] method on [`HashMap`][`HashMap`]
+/// (provided by the `IntoIterator` trait). See its documentation for more.
+///
+/// [`into_iter`]: struct.HashMap.html#method.into_iter
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<K, V> {
     pub(super) inner: table::IntoIter<K, V>,
 }
 
-/// HashMap keys iterator.
+/// An iterator over the keys of a `HashMap`.
+///
+/// This `struct` is created by the [`keys`] method on [`HashMap`]. See its
+/// documentation for more.
+///
+/// [`keys`]: struct.HashMap.html#method.keys
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Keys<'a, K: 'a, V: 'a> {
     inner: Iter<'a, K, V>,
@@ -1394,7 +1415,13 @@ impl<'a, K: Debug, V: Debug> fmt::Debug for Keys<'a, K, V> {
     }
 }
 
-/// HashMap values iterator.
+/// An iterator over the values of a `HashMap`.
+///
+/// This `struct` is created by the [`values`] method on [`HashMap`]. See its
+/// documentation for more.
+///
+/// [`values`]: struct.HashMap.html#method.values
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Values<'a, K: 'a, V: 'a> {
     inner: Iter<'a, K, V>,
@@ -1417,13 +1444,25 @@ impl<'a, K: Debug, V: Debug> fmt::Debug for Values<'a, K, V> {
     }
 }
 
-/// HashMap drain iterator.
+/// A draining iterator over the entries of a `HashMap`.
+///
+/// This `struct` is created by the [`drain`] method on [`HashMap`]. See its
+/// documentation for more.
+///
+/// [`drain`]: struct.HashMap.html#method.drain
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "drain", since = "1.6.0")]
 pub struct Drain<'a, K: 'a, V: 'a> {
     pub(super) inner: table::Drain<'a, K, V>,
 }
 
-/// Mutable HashMap values iterator.
+/// A mutable iterator over the values of a `HashMap`.
+///
+/// This `struct` is created by the [`values_mut`] method on [`HashMap`]. See its
+/// documentation for more.
+///
+/// [`values_mut`]: struct.HashMap.html#method.values_mut
+/// [`HashMap`]: struct.HashMap.html
 #[stable(feature = "map_values_mut", since = "1.10.0")]
 pub struct ValuesMut<'a, K: 'a, V: 'a> {
     inner: IterMut<'a, K, V>,
@@ -1470,19 +1509,20 @@ 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`].
+/// A view into a single entry in a map, which may either 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.
+    /// An occupied entry.
     #[stable(feature = "rust1", since = "1.0.0")]
     Occupied(#[stable(feature = "rust1", since = "1.0.0")]
              OccupiedEntry<'a, K, V>),
 
-    /// A vacant Entry.
+    /// A vacant entry.
     #[stable(feature = "rust1", since = "1.0.0")]
     Vacant(#[stable(feature = "rust1", since = "1.0.0")]
            VacantEntry<'a, K, V>),
@@ -1506,7 +1546,7 @@ impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Entry<'a, K, V> {
     }
 }
 
-/// A view into a single occupied location in a HashMap.
+/// A view into an occupied entry in a `HashMap`.
 /// It is part of the [`Entry`] enum.
 ///
 /// [`Entry`]: enum.Entry.html
@@ -1526,7 +1566,7 @@ impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> {
     }
 }
 
-/// A view into a single empty location in a HashMap.
+/// A view into a vacant entry in a `HashMap`.
 /// It is part of the [`Entry`] enum.
 ///
 /// [`Entry`]: enum.Entry.html
@@ -1818,6 +1858,80 @@ impl<'a, K, V> fmt::Debug for Drain<'a, K, V>
     }
 }
 
+/// A place for insertion to a `Entry`.
+///
+/// See [`HashMap::entry`](struct.HashMap.html#method.entry) for details.
+#[must_use = "places do nothing unless written to with `<-` syntax"]
+#[unstable(feature = "collection_placement",
+           reason = "struct name and placement protocol is subject to change",
+           issue = "30172")]
+pub struct EntryPlace<'a, K: 'a, V: 'a> {
+    bucket: FullBucketMut<'a, K, V>,
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "struct name and placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for EntryPlace<'a, K, V> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("EntryPlace")
+            .field("key", self.bucket.read().0)
+            .field("value", self.bucket.read().1)
+            .finish()
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "struct name and placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> Drop for EntryPlace<'a, K, V> {
+    fn drop(&mut self) {
+        // Inplacement insertion failed. Only key need to drop.
+        // The value is failed to insert into map.
+        unsafe { self.bucket.remove_key() };
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> Placer<V> for Entry<'a, K, V> {
+    type Place = EntryPlace<'a, K, V>;
+
+    fn make_place(self) -> EntryPlace<'a, K, V> {
+        let b = match self {
+            Occupied(mut o) => {
+                unsafe { ptr::drop_in_place(o.elem.read_mut().1); }
+                o.elem
+            }
+            Vacant(v) => {
+                unsafe { v.insert_key() }
+            }
+        };
+        EntryPlace { bucket: b }
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> Place<V> for EntryPlace<'a, K, V> {
+    fn pointer(&mut self) -> *mut V {
+        self.bucket.read_mut().1
+    }
+}
+
+#[unstable(feature = "collection_placement",
+           reason = "placement protocol is subject to change",
+           issue = "30172")]
+impl<'a, K, V> InPlace<V> for EntryPlace<'a, K, V> {
+    type Owner = ();
+
+    unsafe fn finalize(self) {
+        mem::forget(self);
+    }
+}
+
 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
@@ -1902,13 +2016,6 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
         self.elem.read().0
     }
 
-    /// Deprecated, renamed to `remove_entry`
-    #[unstable(feature = "map_entry_recover_keys", issue = "34285")]
-    #[rustc_deprecated(since = "1.12.0", reason = "renamed to `remove_entry`")]
-    pub fn remove_pair(self) -> (K, V) {
-        self.remove_entry()
-    }
-
     /// Take the ownership of the key and value from the map.
     ///
     /// # Examples
@@ -2108,7 +2215,7 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn insert(self, value: V) -> &'a mut V {
-        match self.elem {
+        let b = match self.elem {
             NeqElem(mut bucket, disp) => {
                 if disp >= DISPLACEMENT_THRESHOLD {
                     bucket.table_mut().set_tag(true);
@@ -2119,7 +2226,28 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
                 if disp >= DISPLACEMENT_THRESHOLD {
                     bucket.table_mut().set_tag(true);
                 }
-                bucket.put(self.hash, self.key, value).into_mut_refs().1
+                bucket.put(self.hash, self.key, value)
+            },
+        };
+        b.into_mut_refs().1
+    }
+
+    // Only used for InPlacement insert. Avoid unnecessary value copy.
+    // The value remains uninitialized.
+    unsafe fn insert_key(self) -> FullBucketMut<'a, K, V> {
+        match self.elem {
+            NeqElem(mut bucket, disp) => {
+                if disp >= DISPLACEMENT_THRESHOLD {
+                    bucket.table_mut().set_tag(true);
+                }
+                let uninit = mem::uninitialized();
+                robin_hood(bucket, disp, self.hash, self.key, uninit)
+            },
+            NoElem(mut bucket, disp) => {
+                if disp >= DISPLACEMENT_THRESHOLD {
+                    bucket.table_mut().set_tag(true);
+                }
+                bucket.put_key(self.hash, self.key)
             },
         }
     }
@@ -2274,10 +2402,9 @@ impl DefaultHasher {
 
 #[stable(feature = "hashmap_default_hasher", since = "1.13.0")]
 impl Default for DefaultHasher {
-    /// Creates a new `DefaultHasher` using [`DefaultHasher::new`]. See
-    /// [`DefaultHasher::new`] documentation for more information.
+    /// Creates a new `DefaultHasher` using [`new`]. See its documentation for more.
     ///
-    /// [`DefaultHasher::new`]: #method.new
+    /// [`new`]: #method.new
     fn default() -> DefaultHasher {
         DefaultHasher::new()
     }
@@ -2392,6 +2519,7 @@ mod test_map {
     use super::RandomState;
     use cell::RefCell;
     use rand::{thread_rng, Rng};
+    use panic;
 
     #[test]
     fn test_zero_capacities() {
@@ -3265,4 +3393,57 @@ mod test_map {
         }
         panic!("Adaptive early resize failed");
     }
+
+    #[test]
+    fn test_placement_in() {
+        let mut map = HashMap::new();
+        map.extend((0..10).map(|i| (i, i)));
+
+        map.entry(100) <- 100;
+        assert_eq!(map[&100], 100);
+
+        map.entry(0) <- 10;
+        assert_eq!(map[&0], 10);
+
+        assert_eq!(map.len(), 11);
+    }
+
+    #[test]
+    fn test_placement_panic() {
+        let mut map = HashMap::new();
+        map.extend((0..10).map(|i| (i, i)));
+
+        fn mkpanic() -> usize { panic!() }
+
+        // modify existing key
+        // when panic happens, previous key is removed.
+        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { map.entry(0) <- mkpanic(); }));
+        assert_eq!(map.len(), 9);
+        assert!(!map.contains_key(&0));
+
+        // add new key
+        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { map.entry(100) <- mkpanic(); }));
+        assert_eq!(map.len(), 9);
+        assert!(!map.contains_key(&100));
+    }
+
+    #[test]
+    fn test_placement_drop() {
+        // correctly drop
+        struct TestV<'a>(&'a mut bool);
+        impl<'a> Drop for TestV<'a> {
+            fn drop(&mut self) {
+                if !*self.0 { panic!("value double drop!"); } // no double drop
+                *self.0 = false;
+            }
+        }
+
+        fn makepanic<'a>() -> TestV<'a> { panic!() }
+
+        let mut can_drop = true;
+        let mut hm = HashMap::new();
+        hm.insert(0, TestV(&mut can_drop));
+        let _ = panic::catch_unwind(panic::AssertUnwindSafe(|| { hm.entry(0) <- makepanic(); }));
+        assert_eq!(hm.len(), 0);
+    }
 }
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index ac0d15472c1..d80df5f18b6 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -24,11 +24,10 @@ use super::map::{self, HashMap, Keys, RandomState};
 // for `bucket.val` in the case of HashSet. I suppose we would need HKT
 // to get rid of it properly.
 
-/// An implementation of a hash set using the underlying representation of a
-/// HashMap where the value is ().
+/// A hash set implemented as a `HashMap` where the value is `()`.
 ///
-/// As with the `HashMap` type, a `HashSet` requires that the elements
-/// implement the `Eq` and `Hash` traits. This can frequently be achieved by
+/// As with the [`HashMap`] type, a `HashSet` requires that the elements
+/// implement the [`Eq`] and [`Hash`] traits. This can frequently be achieved by
 /// using `#[derive(PartialEq, Eq, Hash)]`. If you implement these yourself,
 /// it is important that the following property holds:
 ///
@@ -40,9 +39,9 @@ use super::map::{self, HashMap, Keys, RandomState};
 ///
 ///
 /// It is a logic error for an item to be modified in such a way that the
-/// item's hash, as determined by the `Hash` trait, or its equality, as
-/// determined by the `Eq` trait, changes while it is in the set. This is
-/// normally only possible through `Cell`, `RefCell`, global state, I/O, or
+/// item's hash, as determined by the [`Hash`] trait, or its equality, as
+/// determined by the [`Eq`] trait, changes while it is in the set. This is
+/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or
 /// unsafe code.
 ///
 /// # Examples
@@ -75,8 +74,8 @@ use super::map::{self, HashMap, Keys, RandomState};
 /// ```
 ///
 /// The easiest way to use `HashSet` with a custom type is to derive
-/// `Eq` and `Hash`. We must also derive `PartialEq`, this will in the
-/// future be implied by `Eq`.
+/// [`Eq`] and [`Hash`]. We must also derive [`PartialEq`], this will in the
+/// future be implied by [`Eq`].
 ///
 /// ```
 /// use std::collections::HashSet;
@@ -99,7 +98,7 @@ use super::map::{self, HashMap, Keys, RandomState};
 /// }
 /// ```
 ///
-/// HashSet with fixed list of elements can be initialized from an array:
+/// A `HashSet` with fixed list of elements can be initialized from an array:
 ///
 /// ```
 /// use std::collections::HashSet;
@@ -110,8 +109,13 @@ use super::map::{self, HashMap, Keys, RandomState};
 ///     // use the values stored in the set
 /// }
 /// ```
-
-
+///
+/// [`Cell`]: ../../std/cell/struct.Cell.html
+/// [`Eq`]: ../../std/cmp/trait.Eq.html
+/// [`Hash`]: ../../std/hash/trait.Hash.html
+/// [`HashMap`]: struct.HashMap.html
+/// [`PartialEq`]: ../../std/cmp/trait.PartialEq.html
+/// [`RefCell`]: ../../std/cell/struct.RefCell.html
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct HashSet<T, S = RandomState> {
@@ -181,7 +185,7 @@ impl<T, S> HashSet<T, S>
         HashSet { map: HashMap::with_hasher(hasher) }
     }
 
-    /// Creates an empty HashSet with with the specified capacity, using
+    /// Creates an empty `HashSet` with with the specified capacity, using
     /// `hasher` to hash the keys.
     ///
     /// The hash set will be able to hold at least `capacity` elements without
@@ -208,7 +212,9 @@ impl<T, S> HashSet<T, S>
         HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) }
     }
 
-    /// Returns a reference to the set's hasher.
+    /// Returns a reference to the set's [`BuildHasher`].
+    ///
+    /// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
     #[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
     pub fn hasher(&self) -> &S {
         self.map.hasher()
@@ -271,7 +277,7 @@ impl<T, S> HashSet<T, S>
     }
 
     /// An iterator visiting all elements in arbitrary order.
-    /// Iterator element type is &'a T.
+    /// The iterator element type is `&'a T`.
     ///
     /// # Examples
     ///
@@ -291,7 +297,7 @@ impl<T, S> HashSet<T, S>
         Iter { iter: self.map.keys() }
     }
 
-    /// Visit the values representing the difference,
+    /// Visits the values representing the difference,
     /// i.e. the values that are in `self` but not in `other`.
     ///
     /// # Examples
@@ -322,7 +328,7 @@ impl<T, S> HashSet<T, S>
         }
     }
 
-    /// Visit the values representing the symmetric difference,
+    /// Visits the values representing the symmetric difference,
     /// i.e. the values that are in `self` or in `other` but not in both.
     ///
     /// # Examples
@@ -350,7 +356,7 @@ impl<T, S> HashSet<T, S>
         SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) }
     }
 
-    /// Visit the values representing the intersection,
+    /// Visits the values representing the intersection,
     /// i.e. the values that are both in `self` and `other`.
     ///
     /// # Examples
@@ -376,7 +382,7 @@ impl<T, S> HashSet<T, S>
         }
     }
 
-    /// Visit the values representing the union,
+    /// Visits the values representing the union,
     /// i.e. all the values in `self` or `other`, without duplicates.
     ///
     /// # Examples
@@ -460,7 +466,7 @@ impl<T, S> HashSet<T, S>
     /// Returns `true` if the set contains a value.
     ///
     /// The value may be any borrowed form of the set's value type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
     /// the value type.
     ///
     /// # Examples
@@ -472,6 +478,9 @@ impl<T, S> HashSet<T, S>
     /// assert_eq!(set.contains(&1), true);
     /// assert_eq!(set.contains(&4), false);
     /// ```
+    ///
+    /// [`Eq`]: ../../std/cmp/trait.Eq.html
+    /// [`Hash`]: ../../std/hash/trait.Hash.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
         where T: Borrow<Q>,
@@ -483,8 +492,11 @@ impl<T, S> HashSet<T, S>
     /// Returns a reference to the value in the set, if any, that is equal to the given value.
     ///
     /// The value may be any borrowed form of the set's value type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
     /// the value type.
+    ///
+    /// [`Eq`]: ../../std/cmp/trait.Eq.html
+    /// [`Hash`]: ../../std/hash/trait.Hash.html
     #[stable(feature = "set_recovery", since = "1.9.0")]
     pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T>
         where T: Borrow<Q>,
@@ -596,7 +608,7 @@ impl<T, S> HashSet<T, S>
     /// present in the set.
     ///
     /// The value may be any borrowed form of the set's value type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
     /// the value type.
     ///
     /// # Examples
@@ -610,6 +622,9 @@ impl<T, S> HashSet<T, S>
     /// assert_eq!(set.remove(&2), true);
     /// assert_eq!(set.remove(&2), false);
     /// ```
+    ///
+    /// [`Eq`]: ../../std/cmp/trait.Eq.html
+    /// [`Hash`]: ../../std/hash/trait.Hash.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
         where T: Borrow<Q>,
@@ -621,8 +636,11 @@ impl<T, S> HashSet<T, S>
     /// Removes and returns the value in the set, if any, that is equal to the given one.
     ///
     /// The value may be any borrowed form of the set's value type, but
-    /// `Hash` and `Eq` on the borrowed form *must* match those for
+    /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
     /// the value type.
+    ///
+    /// [`Eq`]: ../../std/cmp/trait.Eq.html
+    /// [`Hash`]: ../../std/hash/trait.Hash.html
     #[stable(feature = "set_recovery", since = "1.9.0")]
     pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T>
         where T: Borrow<Q>,
@@ -638,7 +656,6 @@ impl<T, S> HashSet<T, S>
     /// # Examples
     ///
     /// ```
-    /// #![feature(retain_hash_collection)]
     /// use std::collections::HashSet;
     ///
     /// let xs = [1,2,3,4,5,6];
@@ -646,7 +663,7 @@ impl<T, S> HashSet<T, S>
     /// set.retain(|&k| k % 2 == 0);
     /// assert_eq!(set.len(), 3);
     /// ```
-    #[unstable(feature = "retain_hash_collection", issue = "36648")]
+    #[stable(feature = "retain_hash_collection", since = "1.18.0")]
     pub fn retain<F>(&mut self, mut f: F)
         where F: FnMut(&T) -> bool
     {
@@ -856,25 +873,49 @@ impl<'a, 'b, T, S> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S>
     }
 }
 
-/// HashSet iterator
+/// An iterator over the items of a `HashSet`.
+///
+/// This `struct` is created by the [`iter`] method on [`HashSet`].
+/// See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`iter`]: struct.HashSet.html#method.iter
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, K: 'a> {
     iter: Keys<'a, K, ()>,
 }
 
-/// HashSet move iterator
+/// An owning iterator over the items of a `HashSet`.
+///
+/// This `struct` is created by the [`into_iter`] method on [`HashSet`][`HashSet`]
+/// (provided by the `IntoIterator` trait). See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`into_iter`]: struct.HashSet.html#method.into_iter
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<K> {
     iter: map::IntoIter<K, ()>,
 }
 
-/// HashSet drain iterator
+/// A draining iterator over the items of a `HashSet`.
+///
+/// This `struct` is created by the [`drain`] method on [`HashSet`].
+/// See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`drain`]: struct.HashSet.html#method.drain
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Drain<'a, K: 'a> {
     iter: map::Drain<'a, K, ()>,
 }
 
-/// Intersection iterator
+/// A lazy iterator producing elements in the intersection of `HashSet`s.
+///
+/// This `struct` is created by the [`intersection`] method on [`HashSet`].
+/// See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`intersection`]: struct.HashSet.html#method.intersection
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Intersection<'a, T: 'a, S: 'a> {
     // iterator of the first set
@@ -883,7 +924,13 @@ pub struct Intersection<'a, T: 'a, S: 'a> {
     other: &'a HashSet<T, S>,
 }
 
-/// Difference iterator
+/// A lazy iterator producing elements in the difference of `HashSet`s.
+///
+/// This `struct` is created by the [`difference`] method on [`HashSet`].
+/// See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`difference`]: struct.HashSet.html#method.difference
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Difference<'a, T: 'a, S: 'a> {
     // iterator of the first set
@@ -892,13 +939,25 @@ pub struct Difference<'a, T: 'a, S: 'a> {
     other: &'a HashSet<T, S>,
 }
 
-/// Symmetric difference iterator.
+/// A lazy iterator producing elements in the symmetric difference of `HashSet`s.
+///
+/// This `struct` is created by the [`symmetric_difference`] method on
+/// [`HashSet`]. See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`symmetric_difference`]: struct.HashSet.html#method.symmetric_difference
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
     iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>,
 }
 
-/// Set union iterator.
+/// A lazy iterator producing elements in the union of `HashSet`s.
+///
+/// This `struct` is created by the [`union`] method on [`HashSet`].
+/// See its documentation for more.
+///
+/// [`HashSet`]: struct.HashSet.html
+/// [`union`]: struct.HashSet.html#method.union
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Union<'a, T: 'a, S: 'a> {
     iter: Chain<Iter<'a, T>, Difference<'a, T, S>>,
@@ -979,9 +1038,7 @@ impl<'a, K> FusedIterator for Iter<'a, K> {}
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<'a, K: fmt::Debug> fmt::Debug for Iter<'a, K> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_list()
-            .entries(self.clone())
-            .finish()
+        f.debug_list().entries(self.clone()).finish()
     }
 }
 
@@ -1008,10 +1065,11 @@ impl<K> FusedIterator for IntoIter<K> {}
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<K: fmt::Debug> fmt::Debug for IntoIter<K> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let entries_iter = self.iter.inner.iter().map(|(k, _)| k);
-        f.debug_list()
-            .entries(entries_iter)
-            .finish()
+        let entries_iter = self.iter
+            .inner
+            .iter()
+            .map(|(k, _)| k);
+        f.debug_list().entries(entries_iter).finish()
     }
 }
 
@@ -1038,10 +1096,11 @@ impl<'a, K> FusedIterator for Drain<'a, K> {}
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<'a, K: fmt::Debug> fmt::Debug for Drain<'a, K> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let entries_iter = self.iter.inner.iter().map(|(k, _)| k);
-        f.debug_list()
-            .entries(entries_iter)
-            .finish()
+        let entries_iter = self.iter
+            .inner
+            .iter()
+            .map(|(k, _)| k);
+        f.debug_list().entries(entries_iter).finish()
     }
 }
 
@@ -1081,12 +1140,10 @@ impl<'a, T, S> Iterator for Intersection<'a, T, S>
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<'a, T, S> fmt::Debug for Intersection<'a, T, S>
     where T: fmt::Debug + Eq + Hash,
-          S: BuildHasher,
+          S: BuildHasher
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_list()
-            .entries(self.clone())
-            .finish()
+        f.debug_list().entries(self.clone()).finish()
     }
 }
 
@@ -1140,12 +1197,10 @@ impl<'a, T, S> FusedIterator for Difference<'a, T, S>
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<'a, T, S> fmt::Debug for Difference<'a, T, S>
     where T: fmt::Debug + Eq + Hash,
-          S: BuildHasher,
+          S: BuildHasher
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_list()
-            .entries(self.clone())
-            .finish()
+        f.debug_list().entries(self.clone()).finish()
     }
 }
 
@@ -1181,12 +1236,10 @@ impl<'a, T, S> FusedIterator for SymmetricDifference<'a, T, S>
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S>
     where T: fmt::Debug + Eq + Hash,
-          S: BuildHasher,
+          S: BuildHasher
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_list()
-            .entries(self.clone())
-            .finish()
+        f.debug_list().entries(self.clone()).finish()
     }
 }
 
@@ -1207,12 +1260,10 @@ impl<'a, T, S> FusedIterator for Union<'a, T, S>
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<'a, T, S> fmt::Debug for Union<'a, T, S>
     where T: fmt::Debug + Eq + Hash,
-          S: BuildHasher,
+          S: BuildHasher
 {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.debug_list()
-            .entries(self.clone())
-            .finish()
+        f.debug_list().entries(self.clone()).finish()
     }
 }
 
@@ -1636,7 +1687,7 @@ mod test_set {
 
     #[test]
     fn test_retain() {
-        let xs = [1,2,3,4,5,6];
+        let xs = [1, 2, 3, 4, 5, 6];
         let mut set: HashSet<isize> = xs.iter().cloned().collect();
         set.retain(|&k| k % 2 == 0);
         assert_eq!(set.len(), 3);
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 0e225b2964f..50c721db849 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -8,13 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use alloc::heap::{EMPTY, allocate, deallocate};
+use alloc::heap::{allocate, deallocate};
 
 use cmp;
 use hash::{BuildHasher, Hash, Hasher};
-use intrinsics::needs_drop;
 use marker;
-use mem::{align_of, size_of};
+use mem::{align_of, size_of, needs_drop};
 use mem;
 use ops::{Deref, DerefMut};
 use ptr::{self, Unique, Shared};
@@ -33,6 +32,7 @@ use self::BucketState::*;
 type HashUint = usize;
 
 const EMPTY_BUCKET: HashUint = 0;
+const EMPTY: usize = 1;
 
 /// Special `Unique<HashUint>` that uses the lower bit of the pointer
 /// to expose a boolean tag.
@@ -49,24 +49,25 @@ impl TaggedHashUintPtr {
 
     #[inline]
     fn set_tag(&mut self, value: bool) {
-        let usize_ptr = &*self.0 as *const *mut HashUint as *mut usize;
+        let mut usize_ptr = self.0.as_ptr() as usize;
         unsafe {
             if value {
-                *usize_ptr |= 1;
+                usize_ptr |= 1;
             } else {
-                *usize_ptr &= !1;
+                usize_ptr &= !1;
             }
+            self.0 = Unique::new(usize_ptr as *mut HashUint)
         }
     }
 
     #[inline]
     fn tag(&self) -> bool {
-        (*self.0 as usize) & 1 == 1
+        (self.0.as_ptr() as usize) & 1 == 1
     }
 
     #[inline]
     fn ptr(&self) -> *mut HashUint {
-        (*self.0 as usize & !1) as *mut HashUint
+        (self.0.as_ptr() as usize & !1) as *mut HashUint
     }
 }
 
@@ -113,7 +114,7 @@ impl TaggedHashUintPtr {
 /// when the RawTable is created and is accessible with the `tag` and `set_tag`
 /// functions.
 pub struct RawTable<K, V> {
-    capacity: usize,
+    capacity_mask: usize,
     size: usize,
     hashes: TaggedHashUintPtr,
 
@@ -125,10 +126,13 @@ pub struct RawTable<K, V> {
 unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
 unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
 
+// An unsafe view of a RawTable bucket
+// Valid indexes are within [0..table_capacity)
 pub struct RawBucket<K, V> {
-    hash: *mut HashUint,
+    hash_start: *mut HashUint,
     // We use *const to ensure covariance with respect to K and V
-    pair: *const (K, V),
+    pair_start: *const (K, V),
+    idx: usize,
     _marker: marker::PhantomData<(K, V)>,
 }
 
@@ -141,7 +145,6 @@ impl<K, V> Clone for RawBucket<K, V> {
 
 pub struct Bucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
@@ -154,13 +157,11 @@ impl<K, V, M: Copy> Clone for Bucket<K, V, M> {
 
 pub struct EmptyBucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
 pub struct FullBucket<K, V, M> {
     raw: RawBucket<K, V>,
-    idx: usize,
     table: M,
 }
 
@@ -232,13 +233,17 @@ fn can_alias_safehash_as_hash() {
     assert_eq!(size_of::<SafeHash>(), size_of::<HashUint>())
 }
 
+// RawBucket methods are unsafe as it's possible to
+// make a RawBucket point to invalid memory using safe code.
 impl<K, V> RawBucket<K, V> {
-    unsafe fn offset(self, count: isize) -> RawBucket<K, V> {
-        RawBucket {
-            hash: self.hash.offset(count),
-            pair: self.pair.offset(count),
-            _marker: marker::PhantomData,
-        }
+    unsafe fn hash(&self) -> *mut HashUint {
+        self.hash_start.offset(self.idx as isize)
+    }
+    unsafe fn pair(&self) -> *mut (K, V) {
+        self.pair_start.offset(self.idx as isize) as *mut (K, V)
+    }
+    unsafe fn hash_pair(&self) -> (*mut HashUint, *mut (K, V)) {
+        (self.hash(), self.pair())
     }
 }
 
@@ -258,7 +263,7 @@ impl<K, V, M> FullBucket<K, V, M> {
     }
     /// Get the raw index.
     pub fn index(&self) -> usize {
-        self.idx
+        self.raw.idx
     }
     /// Get the raw bucket.
     pub fn raw(&self) -> RawBucket<K, V> {
@@ -280,7 +285,7 @@ impl<K, V, M> EmptyBucket<K, V, M> {
 impl<K, V, M> Bucket<K, V, M> {
     /// Get the raw index.
     pub fn index(&self) -> usize {
-        self.idx
+        self.raw.idx
     }
     /// get the table.
     pub fn into_table(self) -> M {
@@ -331,12 +336,11 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
         Bucket::at_index(table, hash.inspect() as usize)
     }
 
-    pub fn new_from(r: RawBucket<K, V>, i: usize, t: M)
+    pub fn new_from(r: RawBucket<K, V>, t: M)
         -> Bucket<K, V, M>
     {
         Bucket {
             raw: r,
-            idx: i,
             table: t,
         }
     }
@@ -346,18 +350,16 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
         // This is an uncommon case though, so avoid it in release builds.
         debug_assert!(table.capacity() > 0,
                       "Table should have capacity at this point");
-        let ib_index = ib_index & (table.capacity() - 1);
+        let ib_index = ib_index & table.capacity_mask;
         Bucket {
-            raw: unsafe { table.first_bucket_raw().offset(ib_index as isize) },
-            idx: ib_index,
+            raw: table.raw_bucket_at(ib_index),
             table: table,
         }
     }
 
     pub fn first(table: M) -> Bucket<K, V, M> {
         Bucket {
-            raw: table.first_bucket_raw(),
-            idx: 0,
+            raw: table.raw_bucket_at(0),
             table: table,
         }
     }
@@ -401,48 +403,30 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
     /// the appropriate types to call most of the other functions in
     /// this module.
     pub fn peek(self) -> BucketState<K, V, M> {
-        match unsafe { *self.raw.hash } {
+        match unsafe { *self.raw.hash() } {
             EMPTY_BUCKET => {
                 Empty(EmptyBucket {
                     raw: self.raw,
-                    idx: self.idx,
                     table: self.table,
                 })
             }
             _ => {
                 Full(FullBucket {
                     raw: self.raw,
-                    idx: self.idx,
                     table: self.table,
                 })
             }
         }
     }
 
-    /// Modifies the bucket pointer in place to make it point to the next slot.
+    /// Modifies the bucket in place to make it point to the next slot.
     pub fn next(&mut self) {
-        self.idx += 1;
-        let range = self.table.capacity();
-        // This code is branchless thanks to a conditional move.
-        let dist = if self.idx & (range - 1) == 0 {
-            1 - range as isize
-        } else {
-            1
-        };
-        unsafe {
-            self.raw = self.raw.offset(dist);
-        }
+        self.raw.idx = self.raw.idx.wrapping_add(1) & self.table.capacity_mask;
     }
 
-    /// Modifies the bucket pointer in place to make it point to the previous slot.
+    /// Modifies the bucket in place to make it point to the previous slot.
     pub fn prev(&mut self) {
-        let range = self.table.capacity();
-        let new_idx = self.idx.wrapping_sub(1) & (range - 1);
-        let dist = (new_idx as isize).wrapping_sub(self.idx as isize);
-        self.idx = new_idx;
-        unsafe {
-            self.raw = self.raw.offset(dist);
-        }
+        self.raw.idx = self.raw.idx.wrapping_sub(1) & self.table.capacity_mask;
     }
 }
 
@@ -458,7 +442,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
     pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -466,7 +449,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
     pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
         let gap = EmptyBucket {
             raw: self.raw,
-            idx: self.idx,
             table: (),
         };
 
@@ -494,15 +476,29 @@ impl<K, V, M> EmptyBucket<K, V, M>
     /// 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> {
         unsafe {
-            *self.raw.hash = hash.inspect();
-            ptr::write(self.raw.pair as *mut (K, V), (key, value));
+            *self.raw.hash() = hash.inspect();
+            ptr::write(self.raw.pair(), (key, value));
 
             self.table.borrow_table_mut().size += 1;
         }
 
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
+            table: self.table,
+        }
+    }
+
+    /// Puts given key, remain value uninitialized.
+    /// It is only used for inplacement insertion.
+    pub unsafe fn put_key(mut self, hash: SafeHash, key: K) -> FullBucket<K, V, M> {
+        *self.raw.hash() = hash.inspect();
+        let pair_ptr = self.raw.pair();
+        ptr::write(&mut (*pair_ptr).0, key);
+
+        self.table.borrow_table_mut().size += 1;
+
+        FullBucket {
+            raw: self.raw,
             table: self.table,
         }
     }
@@ -520,7 +516,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
     pub fn into_bucket(self) -> Bucket<K, V, M> {
         Bucket {
             raw: self.raw,
-            idx: self.idx,
             table: self.table,
         }
     }
@@ -530,7 +525,6 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
     pub fn stash(self) -> FullBucket<K, V, Self> {
         FullBucket {
             raw: self.raw,
-            idx: self.idx,
             table: self,
         }
     }
@@ -544,17 +538,20 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> {
         // Calculates the distance one has to travel when going from
         // `hash mod capacity` onwards to `idx mod capacity`, wrapping around
         // if the destination is not reached before the end of the table.
-        (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
+        (self.raw.idx.wrapping_sub(self.hash().inspect() as usize)) & self.table.capacity_mask
     }
 
     #[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.pair).0, &(*self.raw.pair).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
+        }
     }
 }
 
@@ -570,17 +567,27 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
         self.table.size -= 1;
 
         unsafe {
-            *self.raw.hash = EMPTY_BUCKET;
-            let (k, v) = ptr::read(self.raw.pair);
+            *self.raw.hash() = EMPTY_BUCKET;
+            let (k, v) = ptr::read(self.raw.pair());
             (EmptyBucket {
                  raw: self.raw,
-                 idx: self.idx,
                  table: self.table,
              },
             k,
             v)
         }
     }
+
+    /// Remove this bucket's `key` from the hashtable.
+    /// Only used for inplacement insertion.
+    /// NOTE: `Value` is uninitialized when this function is called, don't try to drop the `Value`.
+    pub unsafe fn remove_key(&mut self) {
+        self.table.size -= 1;
+
+        *self.raw.hash() = EMPTY_BUCKET;
+        let pair_ptr = self.raw.pair();
+        ptr::drop_in_place(&mut (*pair_ptr).0); // only drop key
+    }
 }
 
 // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases
@@ -590,8 +597,8 @@ impl<K, V, M> FullBucket<K, V, M>
 {
     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, old_val) = ptr::replace(self.raw.pair as *mut (K, V), (k, v));
+            let old_hash = ptr::replace(self.raw.hash() as *mut SafeHash, h);
+            let (old_key, old_val) = ptr::replace(self.raw.pair(), (k, v));
 
             (old_hash, old_key, old_val)
         }
@@ -603,8 +610,10 @@ impl<K, V, M> FullBucket<K, V, M>
 {
     /// Gets mutable references to the key and value at a given index.
     pub fn read_mut(&mut self) -> (&mut K, &mut V) {
-        let pair_mut = self.raw.pair as *mut (K, V);
-        unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
+        }
     }
 }
 
@@ -617,7 +626,10 @@ impl<'t, K, V, M> FullBucket<K, V, M>
     /// 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.pair).0, &(*self.raw.pair).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
+        }
     }
 }
 
@@ -627,8 +639,10 @@ impl<'t, K, V, M> FullBucket<K, V, M>
     /// 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) {
-        let pair_mut = self.raw.pair as *mut (K, V);
-        unsafe { (&mut (*pair_mut).0, &mut (*pair_mut).1) }
+        unsafe {
+            let pair_ptr = self.raw.pair();
+            (&mut (*pair_ptr).0, &mut (*pair_ptr).1)
+        }
     }
 }
 
@@ -640,22 +654,23 @@ impl<K, V, M> GapThenFull<K, V, M>
         &self.full
     }
 
-    pub fn into_bucket(self) -> Bucket<K, V, M> {
-        self.full.into_bucket()
+    pub fn into_table(self) -> M {
+        self.full.into_table()
     }
 
     pub fn shift(mut self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> {
         unsafe {
-            *self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
-            ptr::copy_nonoverlapping(self.full.raw.pair, self.gap.raw.pair as *mut (K, V), 1);
+            let (gap_hash, gap_pair) = self.gap.raw.hash_pair();
+            let (full_hash, full_pair) = self.full.raw.hash_pair();
+            *gap_hash = mem::replace(&mut *full_hash, EMPTY_BUCKET);
+            ptr::copy_nonoverlapping(full_pair, gap_pair, 1);
         }
 
-        let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
+        let FullBucket { raw: prev_raw, .. } = self.full;
 
         match self.full.next().peek() {
             Full(bucket) => {
                 self.gap.raw = prev_raw;
-                self.gap.idx = prev_idx;
 
                 self.full = bucket;
 
@@ -734,7 +749,7 @@ impl<K, V> RawTable<K, V> {
         if capacity == 0 {
             return RawTable {
                 size: 0,
-                capacity: 0,
+                capacity_mask: capacity.wrapping_sub(1),
                 hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint),
                 marker: marker::PhantomData,
             };
@@ -774,25 +789,27 @@ impl<K, V> RawTable<K, V> {
         let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
 
         RawTable {
-            capacity: capacity,
+            capacity_mask: capacity.wrapping_sub(1),
             size: 0,
             hashes: TaggedHashUintPtr::new(hashes),
             marker: marker::PhantomData,
         }
     }
 
-    fn first_bucket_raw(&self) -> RawBucket<K, V> {
-        let hashes_size = self.capacity * size_of::<HashUint>();
-        let pairs_size = self.capacity * size_of::<(K, V)>();
+    fn raw_bucket_at(&self, index: usize) -> RawBucket<K, V> {
+        let hashes_size = self.capacity() * size_of::<HashUint>();
+        let pairs_size = self.capacity() * size_of::<(K, V)>();
 
-        let buffer = self.hashes.ptr() as *mut u8;
         let (pairs_offset, _, oflo) =
             calculate_offsets(hashes_size, pairs_size, align_of::<(K, V)>());
         debug_assert!(!oflo, "capacity overflow");
+
+        let buffer = self.hashes.ptr() as *mut u8;
         unsafe {
             RawBucket {
-                hash: self.hashes.ptr(),
-                pair: buffer.offset(pairs_offset as isize) as *const _,
+                hash_start: buffer as *mut HashUint,
+                pair_start: buffer.offset(pairs_offset as isize) as *const (K, V),
+                idx: index,
                 _marker: marker::PhantomData,
             }
         }
@@ -810,7 +827,7 @@ impl<K, V> RawTable<K, V> {
 
     /// The hashtable's capacity, similar to a vector's.
     pub fn capacity(&self) -> usize {
-        self.capacity
+        self.capacity_mask.wrapping_add(1)
     }
 
     /// The number of elements ever `put` in the hashtable, minus the number
@@ -821,8 +838,8 @@ impl<K, V> RawTable<K, V> {
 
     fn raw_buckets(&self) -> RawBuckets<K, V> {
         RawBuckets {
-            raw: self.first_bucket_raw(),
-            hashes_end: unsafe { self.hashes.ptr().offset(self.capacity as isize) },
+            raw: self.raw_bucket_at(0),
+            elems_left: self.size,
             marker: marker::PhantomData,
         }
     }
@@ -830,25 +847,23 @@ impl<K, V> RawTable<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.raw_buckets(),
-            elems_left: self.size(),
         }
     }
 
     pub fn iter_mut(&mut self) -> IterMut<K, V> {
         IterMut {
             iter: self.raw_buckets(),
-            elems_left: self.size(),
             _marker: marker::PhantomData,
         }
     }
 
     pub fn into_iter(self) -> IntoIter<K, V> {
-        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
         IntoIter {
             iter: RawBuckets {
                 raw: raw,
-                hashes_end: hashes_end,
+                elems_left: elems_left,
                 marker: marker::PhantomData,
             },
             table: self,
@@ -856,12 +871,12 @@ impl<K, V> RawTable<K, V> {
     }
 
     pub fn drain(&mut self) -> Drain<K, V> {
-        let RawBuckets { raw, hashes_end, .. } = self.raw_buckets();
+        let RawBuckets { raw, elems_left, .. } = self.raw_buckets();
         // Replace the marker regardless of lifetime bounds on parameters.
         Drain {
             iter: RawBuckets {
                 raw: raw,
-                hashes_end: hashes_end,
+                elems_left: elems_left,
                 marker: marker::PhantomData,
             },
             table: unsafe { Shared::new(self) },
@@ -869,15 +884,21 @@ impl<K, V> RawTable<K, V> {
         }
     }
 
-    /// Returns an iterator that copies out each entry. Used while the table
-    /// is being dropped.
-    unsafe fn rev_move_buckets(&mut self) -> RevMoveBuckets<K, V> {
-        let raw_bucket = self.first_bucket_raw();
-        RevMoveBuckets {
-            raw: raw_bucket.offset(self.capacity as isize),
-            hashes_end: raw_bucket.hash,
-            elems_left: self.size,
-            marker: marker::PhantomData,
+    /// Drops buckets in reverse order. It leaves the table in an inconsistent
+    /// state and should only be used for dropping the table's remaining
+    /// entries. It's used in the implementation of Drop.
+    unsafe fn rev_drop_buckets(&mut self) {
+        // initialize the raw bucket past the end of the table
+        let mut raw = self.raw_bucket_at(self.capacity());
+        let mut elems_left = self.size;
+
+        while elems_left != 0 {
+            raw.idx -= 1;
+
+            if *raw.hash() != EMPTY_BUCKET {
+                elems_left -= 1;
+                ptr::drop_in_place(raw.pair());
+            }
         }
     }
 
@@ -896,7 +917,7 @@ impl<K, V> RawTable<K, V> {
 /// this interface is safe, it's not used outside this module.
 struct RawBuckets<'a, K, V> {
     raw: RawBucket<K, V>,
-    hashes_end: *mut HashUint,
+    elems_left: usize,
 
     // Strictly speaking, this should be &'a (K,V), but that would
     // require that K:'a, and we often use RawBuckets<'static...> for
@@ -911,7 +932,7 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
     fn clone(&self) -> RawBuckets<'a, K, V> {
         RawBuckets {
             raw: self.raw,
-            hashes_end: self.hashes_end,
+            elems_left: self.elems_left,
             marker: marker::PhantomData,
         }
     }
@@ -922,62 +943,36 @@ impl<'a, K, V> Iterator for RawBuckets<'a, K, V> {
     type Item = RawBucket<K, V>;
 
     fn next(&mut self) -> Option<RawBucket<K, V>> {
-        while self.raw.hash != self.hashes_end {
-            unsafe {
-                // We are swapping out the pointer to a bucket and replacing
-                // it with the pointer to the next one.
-                let prev = ptr::replace(&mut self.raw, self.raw.offset(1));
-                if *prev.hash != EMPTY_BUCKET {
-                    return Some(prev);
-                }
-            }
-        }
-
-        None
-    }
-}
-
-/// An iterator that moves out buckets in reverse order. It leaves the table
-/// in an inconsistent state and should only be used for dropping
-/// the table's remaining entries. It's used in the implementation of Drop.
-struct RevMoveBuckets<'a, K, V> {
-    raw: RawBucket<K, V>,
-    hashes_end: *mut HashUint,
-    elems_left: usize,
-
-    // As above, `&'a (K,V)` would seem better, but we often use
-    // 'static for the lifetime, and this is not a publicly exposed
-    // type.
-    marker: marker::PhantomData<&'a ()>,
-}
-
-impl<'a, K, V> Iterator for RevMoveBuckets<'a, K, V> {
-    type Item = (K, V);
-
-    fn next(&mut self) -> Option<(K, V)> {
         if self.elems_left == 0 {
             return None;
         }
 
         loop {
-            debug_assert!(self.raw.hash != self.hashes_end);
-
             unsafe {
-                self.raw = self.raw.offset(-1);
-
-                if *self.raw.hash != EMPTY_BUCKET {
+                let item = self.raw;
+                self.raw.idx += 1;
+                if *item.hash() != EMPTY_BUCKET {
                     self.elems_left -= 1;
-                    return Some(ptr::read(self.raw.pair));
+                    return Some(item);
                 }
             }
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        (self.elems_left, Some(self.elems_left))
+    }
+}
+
+impl<'a, K, V> ExactSizeIterator for RawBuckets<'a, K, V> {
+    fn len(&self) -> usize {
+        self.elems_left
+    }
 }
 
 /// Iterator over shared references to entries in a table.
 pub struct Iter<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
-    elems_left: usize,
 }
 
 unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
@@ -988,16 +983,13 @@ 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,
         }
     }
 }
 
-
 /// Iterator over mutable references to entries in a table.
 pub struct IterMut<'a, K: 'a, V: 'a> {
     iter: RawBuckets<'a, K, V>,
-    elems_left: usize,
     // To ensure invariance with respect to V
     _marker: marker::PhantomData<&'a mut V>,
 }
@@ -1011,7 +1003,6 @@ impl<'a, K: 'a, V: 'a> IterMut<'a, K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.elems_left,
         }
     }
 }
@@ -1029,7 +1020,6 @@ impl<K, V> IntoIter<K, V> {
     pub fn iter(&self) -> Iter<K, V> {
         Iter {
             iter: self.iter.clone(),
-            elems_left: self.table.size,
         }
     }
 }
@@ -1046,11 +1036,8 @@ unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
 
 impl<'a, K, V> Drain<'a, K, V> {
     pub fn iter(&self) -> Iter<K, V> {
-        unsafe {
-            Iter {
-                iter: self.iter.clone(),
-                elems_left: (**self.table).size,
-            }
+        Iter {
+            iter: self.iter.clone(),
         }
     }
 }
@@ -1059,19 +1046,20 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
 
     fn next(&mut self) -> Option<(&'a K, &'a V)> {
-        self.iter.next().map(|bucket| {
-            self.elems_left -= 1;
-            unsafe { (&(*bucket.pair).0, &(*bucket.pair).1) }
+        self.iter.next().map(|raw| unsafe {
+            let pair_ptr = raw.pair();
+            (&(*pair_ptr).0, &(*pair_ptr).1)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.elems_left, Some(self.elems_left))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {
     fn len(&self) -> usize {
-        self.elems_left
+        self.iter.len()
     }
 }
 
@@ -1079,20 +1067,20 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
     type Item = (&'a K, &'a mut V);
 
     fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
-        self.iter.next().map(|bucket| {
-            self.elems_left -= 1;
-            let pair_mut = bucket.pair as *mut (K, V);
-            unsafe { (&(*pair_mut).0, &mut (*pair_mut).1) }
+        self.iter.next().map(|raw| unsafe {
+            let pair_ptr = raw.pair();
+            (&(*pair_ptr).0, &mut (*pair_ptr).1)
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.elems_left, Some(self.elems_left))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
     fn len(&self) -> usize {
-        self.elems_left
+        self.iter.len()
     }
 }
 
@@ -1100,23 +1088,23 @@ impl<K, V> Iterator for IntoIter<K, V> {
     type Item = (SafeHash, K, V);
 
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
-        self.iter.next().map(|bucket| {
+        self.iter.next().map(|raw| {
             self.table.size -= 1;
             unsafe {
-                let (k, v) = ptr::read(bucket.pair);
-                (SafeHash { hash: *bucket.hash }, k, v)
+                let (k, v) = ptr::read(raw.pair());
+                (SafeHash { hash: *raw.hash() }, k, v)
             }
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = self.table.size();
-        (size, Some(size))
+        self.iter.size_hint()
     }
 }
+
 impl<K, V> ExactSizeIterator for IntoIter<K, V> {
     fn len(&self) -> usize {
-        self.table.size()
+        self.iter().len()
     }
 }
 
@@ -1125,23 +1113,23 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
 
     #[inline]
     fn next(&mut self) -> Option<(SafeHash, K, V)> {
-        self.iter.next().map(|bucket| {
+        self.iter.next().map(|raw| {
             unsafe {
-                (**self.table).size -= 1;
-                let (k, v) = ptr::read(bucket.pair);
-                (SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) }, k, v)
+                self.table.as_mut().size -= 1;
+                let (k, v) = ptr::read(raw.pair());
+                (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v)
             }
         })
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        let size = unsafe { (**self.table).size() };
-        (size, Some(size))
+        self.iter.size_hint()
     }
 }
+
 impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
     fn len(&self) -> usize {
-        unsafe { (**self.table).size() }
+        self.iter.len()
     }
 }
 
@@ -1154,30 +1142,21 @@ impl<'a, K: 'a, V: 'a> Drop for Drain<'a, K, V> {
 impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
     fn clone(&self) -> RawTable<K, V> {
         unsafe {
-            let mut new_ht = RawTable::new_uninitialized(self.capacity());
-
-            {
-                let cap = self.capacity();
-                let mut new_buckets = Bucket::first(&mut new_ht);
-                let mut buckets = Bucket::first(self);
-                while buckets.index() != cap {
-                    match buckets.peek() {
-                        Full(full) => {
-                            let (h, k, v) = {
-                                let (k, v) = full.read();
-                                (full.hash(), k.clone(), v.clone())
-                            };
-                            *new_buckets.raw.hash = h.inspect();
-                            ptr::write(new_buckets.raw.pair as *mut (K, V), (k, v));
-                        }
-                        Empty(..) => {
-                            *new_buckets.raw.hash = EMPTY_BUCKET;
-                        }
-                    }
-                    new_buckets.next();
-                    buckets.next();
+            let cap = self.capacity();
+            let mut new_ht = RawTable::new_uninitialized(cap);
+
+            let mut new_buckets = new_ht.raw_bucket_at(0);
+            let mut buckets = self.raw_bucket_at(0);
+            while buckets.idx < cap {
+                *new_buckets.hash() = *buckets.hash();
+                if *new_buckets.hash() != EMPTY_BUCKET {
+                    let pair_ptr = buckets.pair();
+                    let kv = ((*pair_ptr).0.clone(), (*pair_ptr).1.clone());
+                    ptr::write(new_buckets.pair(), kv);
                 }
-            };
+                buckets.idx += 1;
+                new_buckets.idx += 1;
+            }
 
             new_ht.size = self.size();
 
@@ -1188,7 +1167,7 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
 
 unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.capacity == 0 {
+        if self.capacity() == 0 {
             return;
         }
 
@@ -1200,12 +1179,12 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
         unsafe {
             if needs_drop::<(K, V)>() {
                 // avoid linear runtime for types that don't need drop
-                for _ in self.rev_move_buckets() {}
+                self.rev_drop_buckets();
             }
         }
 
-        let hashes_size = self.capacity * size_of::<HashUint>();
-        let pairs_size = self.capacity * size_of::<(K, V)>();
+        let hashes_size = self.capacity() * size_of::<HashUint>();
+        let pairs_size = self.capacity() * size_of::<(K, V)>();
         let (align, _, size, oflo) = calculate_allocation(hashes_size,
                                                           align_of::<HashUint>(),
                                                           pairs_size,
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index 8884d0688b8..506bf717337 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -157,29 +157,29 @@
 //! information to do this itself. Therefore, it is up to us programmers to give
 //! it hints.
 //!
-//! Any `with_capacity()` constructor will instruct the collection to allocate
+//! Any `with_capacity` constructor will instruct the collection to allocate
 //! enough space for the specified number of elements. Ideally this will be for
 //! exactly that many elements, but some implementation details may prevent
 //! this. [`Vec`] and [`VecDeque`] can be relied on to allocate exactly the
-//! requested amount, though. Use `with_capacity()` when you know exactly how many
+//! requested amount, though. Use `with_capacity` when you know exactly how many
 //! elements will be inserted, or at least have a reasonable upper-bound on that
 //! number.
 //!
-//! When anticipating a large influx of elements, the `reserve()` family of
+//! When anticipating a large influx of elements, the `reserve` family of
 //! methods can be used to hint to the collection how much room it should make
-//! for the coming items. As with `with_capacity()`, the precise behavior of
+//! for the coming items. As with `with_capacity`, the precise behavior of
 //! these methods will be specific to the collection of interest.
 //!
 //! For optimal performance, collections will generally avoid shrinking
 //! themselves. If you believe that a collection will not soon contain any more
-//! elements, or just really need the memory, the `shrink_to_fit()` method prompts
+//! elements, or just really need the memory, the `shrink_to_fit` method prompts
 //! the collection to shrink the backing array to the minimum size capable of
 //! holding its elements.
 //!
 //! Finally, if ever you're interested in what the actual capacity of the
-//! collection is, most collections provide a `capacity()` method to query this
+//! collection is, most collections provide a `capacity` method to query this
 //! information on demand. This can be useful for debugging purposes, or for
-//! use with the `reserve()` methods.
+//! use with the `reserve` methods.
 //!
 //! ## Iterators
 //!
@@ -194,11 +194,11 @@
 //!
 //! All of the standard collections provide several iterators for performing
 //! bulk manipulation of their contents. The three primary iterators almost
-//! every collection should provide are `iter()`, `iter_mut()`, and `into_iter()`.
+//! every collection should provide are `iter`, `iter_mut`, and `into_iter`.
 //! Some of these are not provided on collections where it would be unsound or
 //! unreasonable to provide them.
 //!
-//! `iter()` provides an iterator of immutable references to all the contents of a
+//! `iter` provides an iterator of immutable references to all the contents of a
 //! collection in the most "natural" order. For sequence collections like [`Vec`],
 //! this means the items will be yielded in increasing order of index starting
 //! at 0. For ordered collections like [`BTreeMap`], this means that the items
@@ -214,8 +214,8 @@
 //! }
 //! ```
 //!
-//! `iter_mut()` provides an iterator of *mutable* references in the same order as
-//! `iter()`. This is great for mutating all the contents of the collection.
+//! `iter_mut` provides an iterator of *mutable* references in the same order as
+//! `iter`. This is great for mutating all the contents of the collection.
 //!
 //! ```
 //! let mut vec = vec![1, 2, 3, 4];
@@ -224,12 +224,12 @@
 //! }
 //! ```
 //!
-//! `into_iter()` transforms the actual collection into an iterator over its
+//! `into_iter` transforms the actual collection into an iterator over its
 //! contents by-value. This is great when the collection itself is no longer
-//! needed, and the values are needed elsewhere. Using `extend()` with `into_iter()`
+//! needed, and the values are needed elsewhere. Using `extend` with `into_iter`
 //! is the main way that contents of one collection are moved into another.
-//! `extend()` automatically calls `into_iter()`, and takes any `T: `[`IntoIterator`].
-//! Calling `collect()` on an iterator itself is also a great way to convert one
+//! `extend` automatically calls `into_iter`, and takes any `T: `[`IntoIterator`].
+//! Calling `collect` on an iterator itself is also a great way to convert one
 //! collection into another. Both of these methods should internally use the
 //! capacity management tools discussed in the previous section to do this as
 //! efficiently as possible.
@@ -248,9 +248,9 @@
 //! ```
 //!
 //! Iterators also provide a series of *adapter* methods for performing common
-//! threads to sequences. Among the adapters are functional favorites like `map()`,
-//! `fold()`, `skip()` and `take()`. Of particular interest to collections is the
-//! `rev()` adapter, that reverses any iterator that supports this operation. Most
+//! threads to sequences. Among the adapters are functional favorites like `map`,
+//! `fold`, `skip` and `take`. Of particular interest to collections is the
+//! `rev` adapter, that reverses any iterator that supports this operation. Most
 //! collections provide reversible iterators as the way to iterate over them in
 //! reverse order.
 //!
@@ -263,27 +263,27 @@
 //!
 //! Several other collection methods also return iterators to yield a sequence
 //! of results but avoid allocating an entire collection to store the result in.
-//! This provides maximum flexibility as `collect()` or `extend()` can be called to
+//! This provides maximum flexibility as `collect` or `extend` can be called to
 //! "pipe" the sequence into any collection if desired. Otherwise, the sequence
 //! can be looped over with a `for` loop. The iterator can also be discarded
 //! after partial use, preventing the computation of the unused items.
 //!
 //! ## Entries
 //!
-//! The `entry()` API is intended to provide an efficient mechanism for
+//! The `entry` API is intended to provide an efficient mechanism for
 //! manipulating the contents of a map conditionally on the presence of a key or
 //! not. The primary motivating use case for this is to provide efficient
 //! accumulator maps. For instance, if one wishes to maintain a count of the
 //! number of times each key has been seen, they will have to perform some
 //! conditional logic on whether this is the first time the key has been seen or
-//! not. Normally, this would require a `find()` followed by an `insert()`,
+//! not. Normally, this would require a `find` followed by an `insert`,
 //! effectively duplicating the search effort on each insertion.
 //!
 //! When a user calls `map.entry(&key)`, the map will search for the key and
 //! then yield a variant of the `Entry` enum.
 //!
 //! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case
-//! the only valid operation is to `insert()` a value into the entry. When this is
+//! the only valid operation is to `insert` a value into the entry. When this is
 //! done, the vacant entry is consumed and converted into a mutable reference to
 //! the value that was inserted. This allows for further manipulation of the
 //! value beyond the lifetime of the search itself. This is useful if complex
@@ -291,14 +291,14 @@
 //! just inserted.
 //!
 //! If an `Occupied(entry)` is yielded, then the key *was* found. In this case,
-//! the user has several options: they can `get()`, `insert()` or `remove()` the
+//! the user has several options: they can `get`, `insert` or `remove` the
 //! value of the occupied entry. Additionally, they can convert the occupied
 //! entry into a mutable reference to its value, providing symmetry to the
-//! vacant `insert()` case.
+//! vacant `insert` case.
 //!
 //! ### Examples
 //!
-//! Here are the two primary ways in which `entry()` is used. First, a simple
+//! Here are the two primary ways in which `entry` is used. First, a simple
 //! example where the logic performed on the values is trivial.
 //!
 //! #### Counting the number of times each character in a string occurs
@@ -322,7 +322,7 @@
 //! ```
 //!
 //! When the logic to be performed on the value is more complex, we may simply
-//! use the `entry()` API to ensure that the value is initialized and perform the
+//! use the `entry` API to ensure that the value is initialized and perform the
 //! logic afterwards.
 //!
 //! #### Tracking the inebriation of customers at a bar
@@ -360,7 +360,7 @@
 //!
 //! # Insert and complex keys
 //!
-//! If we have a more complex key, calls to `insert()` will
+//! If we have a more complex key, calls to `insert` will
 //! not update the value of the key. For example:
 //!
 //! ```
@@ -442,16 +442,14 @@ mod hash;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub mod hash_map {
-    //! A hash map implementation which uses linear probing with Robin
-    //! Hood bucket stealing.
+    //! A hash map implemented with linear probing and 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 {
-    //! An implementation of a hash set using the underlying representation of a
-    //! HashMap where the value is ().
+    //! A hash set implemented as 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 64eb52e28bc..27b40793ff6 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -13,6 +13,13 @@
 //! This module contains functions to inspect various aspects such as
 //! environment variables, process arguments, the current directory, and various
 //! other important directories.
+//!
+//! There are several functions and structs in this module that have a
+//! counterpart ending in `os`. Those ending in `os` will return an [`OsString`]
+//! and those without will be returning a [`String`].
+//!
+//! [`OsString`]: ../../std/ffi/struct.OsString.html
+//! [`String`]: ../string/struct.String.html
 
 #![stable(feature = "env", since = "1.0.0")]
 
@@ -43,16 +50,19 @@ use sys::os as os_imp;
 /// use std::env;
 ///
 /// // We assume that we are in a valid directory.
-/// let p = env::current_dir().unwrap();
-/// println!("The current directory is {}", p.display());
+/// let path = env::current_dir().unwrap();
+/// println!("The current directory is {}", path.display());
 /// ```
 #[stable(feature = "env", since = "1.0.0")]
 pub fn current_dir() -> io::Result<PathBuf> {
     os_imp::getcwd()
 }
 
-/// Changes the current working directory to the specified path, returning
-/// whether the change was completed successfully or not.
+/// Changes the current working directory to the specified path.
+///
+/// Returns an [`Err`] if the operation fails.
+///
+/// [`Err`]: ../../std/result/enum.Result.html#method.err
 ///
 /// # Examples
 ///
@@ -65,13 +75,14 @@ pub fn current_dir() -> io::Result<PathBuf> {
 /// println!("Successfully changed working directory to {}!", root.display());
 /// ```
 #[stable(feature = "env", since = "1.0.0")]
-pub fn set_current_dir<P: AsRef<Path>>(p: P) -> io::Result<()> {
-    os_imp::chdir(p.as_ref())
+pub fn set_current_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
+    os_imp::chdir(path.as_ref())
 }
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
-/// This structure is created through the [`std::env::vars`] function.
+/// This structure is created by the [`std::env::vars`] function. See its
+/// documentation for more.
 ///
 /// [`std::env::vars`]: fn.vars.html
 #[stable(feature = "env", since = "1.0.0")]
@@ -79,7 +90,8 @@ pub struct Vars { inner: VarsOs }
 
 /// An iterator over a snapshot of the environment variables of this process.
 ///
-/// This structure is created through the [`std::env::vars_os`] function.
+/// This structure is created by the [`std::env::vars_os`] function. See
+/// its documentation for more.
 ///
 /// [`std::env::vars_os`]: fn.vars_os.html
 #[stable(feature = "env", since = "1.0.0")]
@@ -173,12 +185,10 @@ impl fmt::Debug for VarsOs {
 
 /// Fetches the environment variable `key` from the current process.
 ///
-/// The returned result is [`Ok(s)`] if the environment variable is present and is
-/// valid unicode. If the environment variable is not present, or it is not
-/// valid unicode, then [`Err`] will be returned.
+/// # Errors
 ///
-/// [`Ok(s)`]: ../result/enum.Result.html#variant.Ok
-/// [`Err`]: ../result/enum.Result.html#variant.Err
+/// * Environment variable is not present
+/// * Environment variable is not valid unicode
 ///
 /// # Examples
 ///
@@ -199,7 +209,7 @@ pub fn var<K: AsRef<OsStr>>(key: K) -> Result<String, VarError> {
 fn _var(key: &OsStr) -> Result<String, VarError> {
     match var_os(key) {
         Some(s) => s.into_string().map_err(VarError::NotUnicode),
-        None => Err(VarError::NotPresent)
+        None => Err(VarError::NotPresent),
     }
 }
 
@@ -230,7 +240,8 @@ fn _var_os(key: &OsStr) -> Option<OsString> {
     })
 }
 
-/// Possible errors from the [`env::var`] function.
+/// The error type for operations interacting with environment variables.
+/// Possibly returned from the [`env::var`] function.
 ///
 /// [`env::var`]: fn.var.html
 #[derive(Debug, PartialEq, Eq, Clone)]
@@ -353,10 +364,13 @@ fn _remove_var(k: &OsStr) {
     })
 }
 
-/// An iterator over `PathBuf` instances for parsing an environment variable
-/// according to platform-specific conventions.
+/// An iterator that splits an environment variable into paths according to
+/// platform-specific conventions.
+///
+/// This structure is created by the [`std::env::split_paths`] function See its
+/// documentation for more.
 ///
-/// This structure is returned from `std::env::split_paths`.
+/// [`std::env::split_paths`]: fn.split_paths.html
 #[stable(feature = "env", since = "1.0.0")]
 pub struct SplitPaths<'a> { inner: os_imp::SplitPaths<'a> }
 
@@ -399,8 +413,10 @@ impl<'a> fmt::Debug for SplitPaths<'a> {
     }
 }
 
-/// Error type returned from `std::env::join_paths` when paths fail to be
-/// joined.
+/// The error type for operations on the `PATH` variable. Possibly returned from
+/// the [`env::join_paths`] function.
+///
+/// [`env::join_paths`]: fn.join_paths.html
 #[derive(Debug)]
 #[stable(feature = "env", since = "1.0.0")]
 pub struct JoinPathsError {
@@ -410,7 +426,7 @@ pub struct JoinPathsError {
 /// Joins a collection of [`Path`]s appropriately for the `PATH`
 /// environment variable.
 ///
-/// Returns an [`OsString`] on success.
+/// # Errors
 ///
 /// Returns an [`Err`][err] (containing an error message) if one of the input
 /// [`Path`]s contains an invalid character for constructing the `PATH`
@@ -490,12 +506,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
+/// # 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`,
+/// # 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
@@ -680,7 +700,7 @@ impl ExactSizeIterator for Args {
     fn is_empty(&self) -> bool { self.inner.is_empty() }
 }
 
-#[stable(feature = "env_iterators", since = "1.11.0")]
+#[stable(feature = "env_iterators", since = "1.12.0")]
 impl DoubleEndedIterator for Args {
     fn next_back(&mut self) -> Option<String> {
         self.inner.next_back().map(|s| s.into_string().unwrap())
@@ -707,7 +727,7 @@ impl ExactSizeIterator for ArgsOs {
     fn is_empty(&self) -> bool { self.inner.is_empty() }
 }
 
-#[stable(feature = "env_iterators", since = "1.11.0")]
+#[stable(feature = "env_iterators", since = "1.12.0")]
 impl DoubleEndedIterator for ArgsOs {
     fn next_back(&mut self) -> Option<OsString> { self.inner.next_back() }
 }
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index e115263d2eb..f56e3a5d780 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -193,7 +193,7 @@ impl From<String> for Box<Error + Send + Sync> {
     }
 }
 
-#[stable(feature = "string_box_error", since = "1.7.0")]
+#[stable(feature = "string_box_error", since = "1.6.0")]
 impl From<String> for Box<Error> {
     fn from(str_err: String) -> Box<Error> {
         let err1: Box<Error + Send + Sync> = From::from(str_err);
@@ -209,13 +209,18 @@ impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
     }
 }
 
-#[stable(feature = "string_box_error", since = "1.7.0")]
+#[stable(feature = "string_box_error", since = "1.6.0")]
 impl<'a> From<&'a str> for Box<Error> {
     fn from(err: &'a str) -> Box<Error> {
         From::from(String::from(err))
     }
 }
 
+#[unstable(feature = "never_type_impls", issue = "35121")]
+impl Error for ! {
+    fn description(&self) -> &str { *self }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Error for str::ParseBoolError {
     fn description(&self) -> &str { "failed to parse bool" }
@@ -277,7 +282,7 @@ impl Error for char::DecodeUtf16Error {
     }
 }
 
-#[stable(feature = "box_error", since = "1.7.0")]
+#[stable(feature = "box_error", since = "1.8.0")]
 impl<T: Error> Error for Box<T> {
     fn description(&self) -> &str {
         Error::description(&**self)
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 544f4f9ddbe..4abad7e24f8 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! The 32-bit floating point type.
+//! This module provides constants which are specific to the implementation
+//! of the `f32` floating point data type. Mathematically significant
+//! numbers are provided in the `consts` sub-module.
 //!
 //! *[See also the `f32` primitive type](../primitive.f32.html).*
 
@@ -20,8 +22,6 @@ use core::num;
 #[cfg(not(test))]
 use intrinsics;
 #[cfg(not(test))]
-use libc::c_int;
-#[cfg(not(test))]
 use num::FpCategory;
 
 
@@ -71,8 +71,6 @@ mod cmath {
         pub fn atan2f(a: c_float, b: c_float) -> c_float;
         pub fn atanf(n: c_float) -> c_float;
         pub fn coshf(n: c_float) -> c_float;
-        pub fn frexpf(n: c_float, value: &mut c_int) -> c_float;
-        pub fn ldexpf(x: c_float, n: c_int) -> c_float;
         pub fn sinhf(n: c_float) -> c_float;
         pub fn tanf(n: c_float) -> c_float;
         pub fn tanhf(n: c_float) -> c_float;
@@ -82,7 +80,7 @@ mod cmath {
     pub use self::shims::*;
     #[cfg(target_env = "msvc")]
     mod shims {
-        use libc::{c_float, c_int};
+        use libc::c_float;
 
         #[inline]
         pub unsafe fn acosf(n: c_float) -> c_float {
@@ -110,20 +108,6 @@ 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;
-            a as c_float
-        }
-
-        #[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
-        }
-
-        #[inline]
         pub unsafe fn sinhf(n: c_float) -> c_float {
             f64::sinh(n as f64) as c_float
         }
@@ -242,40 +226,6 @@ impl f32 {
     #[inline]
     pub fn classify(self) -> FpCategory { num::Float::classify(self) }
 
-    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
-    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
-    /// The floating point encoding is documented in the [Reference][floating-point].
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// use std::f32;
-    ///
-    /// let num = 2.0f32;
-    ///
-    /// // (8388608, -22, 1)
-    /// let (mantissa, exponent, sign) = num.integer_decode();
-    /// let sign_f = sign as f32;
-    /// let mantissa_f = mantissa as f32;
-    /// let exponent_f = num.powf(exponent as f32);
-    ///
-    /// // 1 * 8388608 * 2^(-22) == 2
-    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
-    ///
-    /// assert!(abs_difference <= f32::EPSILON);
-    /// ```
-    /// [floating-point]: ../reference/types.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.
     ///
     /// ```
@@ -710,89 +660,6 @@ impl f32 {
     #[inline]
     pub fn to_radians(self) -> f32 { num::Float::to_radians(self) }
 
-    /// Constructs a floating point number of `x*2^exp`.
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// use std::f32;
-    /// // 3*2^2 - 12 == 0
-    /// let abs_difference = (f32::ldexp(3.0, 2) - 12.0).abs();
-    ///
-    /// assert!(abs_difference <= f32::EPSILON);
-    /// ```
-    #[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) }
-    }
-
-    /// Breaks the number into a normalized fraction and a base-2 exponent,
-    /// satisfying:
-    ///
-    ///  * `self = x * 2^exp`
-    ///  * `0.5 <= abs(x) < 1.0`
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// use std::f32;
-    ///
-    /// let x = 4.0f32;
-    ///
-    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
-    /// let f = x.frexp();
-    /// let abs_difference_0 = (f.0 - 0.5).abs();
-    /// let abs_difference_1 = (f.1 as f32 - 3.0).abs();
-    ///
-    /// assert!(abs_difference_0 <= f32::EPSILON);
-    /// assert!(abs_difference_1 <= f32::EPSILON);
-    /// ```
-    #[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 {
-            let mut exp = 0;
-            let x = cmath::frexpf(self, &mut exp);
-            (x, exp as isize)
-        }
-    }
-
-    /// Returns the next representable floating-point value in the direction of
-    /// `other`.
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// use std::f32;
-    ///
-    /// let x = 1.0f32;
-    ///
-    /// let abs_diff = (x.next_after(2.0) - 1.00000011920928955078125_f32).abs();
-    ///
-    /// assert!(abs_diff <= f32::EPSILON);
-    /// ```
-    #[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) }
-    }
-
     /// Returns the maximum of the two numbers.
     ///
     /// ```
@@ -1224,6 +1091,68 @@ impl f32 {
     pub fn atanh(self) -> f32 {
         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
     }
+
+    /// Raw transmutation to `u32`.
+    ///
+    /// Converts the `f32` into its raw memory representation,
+    /// similar to the `transmute` function.
+    ///
+    /// Note that this function is distinct from casting.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_bits_conv)]
+    /// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting!
+    /// assert_eq!((12.5f32).to_bits(), 0x41480000);
+    ///
+    /// ```
+    #[unstable(feature = "float_bits_conv", reason = "recently added", issue = "40470")]
+    #[inline]
+    pub fn to_bits(self) -> u32 {
+        unsafe { ::mem::transmute(self) }
+    }
+
+    /// Raw transmutation from `u32`.
+    ///
+    /// Converts the given `u32` containing the float's raw memory
+    /// representation into the `f32` type, similar to the
+    /// `transmute` function.
+    ///
+    /// There is only one difference to a bare `transmute`:
+    /// Due to the implications onto Rust's safety promises being
+    /// uncertain, if the representation of a signaling NaN "sNaN" float
+    /// is passed to the function, the implementation is allowed to
+    /// return a quiet NaN instead.
+    ///
+    /// Note that this function is distinct from casting.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_bits_conv)]
+    /// use std::f32;
+    /// let v = f32::from_bits(0x41480000);
+    /// let difference = (v - 12.5).abs();
+    /// assert!(difference <= 1e-5);
+    /// // Example for a signaling NaN value:
+    /// let snan = 0x7F800001;
+    /// assert_ne!(f32::from_bits(snan).to_bits(), snan);
+    /// ```
+    #[unstable(feature = "float_bits_conv", reason = "recently added", issue = "40470")]
+    #[inline]
+    pub fn from_bits(mut v: u32) -> Self {
+        const EXP_MASK: u32   = 0x7F800000;
+        const QNAN_MASK: u32  = 0x00400000;
+        const FRACT_MASK: u32 = 0x007FFFFF;
+        if v & EXP_MASK == EXP_MASK && v & FRACT_MASK != 0 {
+            // If we have a NaN value, we
+            // convert signaling NaN values to quiet NaN
+            // by setting the the highest bit of the fraction
+            v |= QNAN_MASK;
+        }
+        unsafe { ::mem::transmute(v) }
+    }
 }
 
 #[cfg(test)]
@@ -1399,23 +1328,6 @@ mod tests {
     }
 
     #[test]
-    #[allow(deprecated)]
-    fn test_integer_decode() {
-        assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
-        assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
-        assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
-        assert_eq!(0f32.integer_decode(), (0, -150, 1));
-        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));
-
-        // 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]
     fn test_floor() {
         assert_approx_eq!(1.0f32.floor(), 1.0f32);
         assert_approx_eq!(1.3f32.floor(), 1.0f32);
@@ -1727,58 +1639,6 @@ mod tests {
     }
 
     #[test]
-    #[allow(deprecated)]
-    fn test_ldexp() {
-        let f1 = 2.0f32.powi(-123);
-        let f2 = 2.0f32.powi(-111);
-        let f3 = 1.75 * 2.0f32.powi(-12);
-        assert_eq!(f32::ldexp(1f32, -123), f1);
-        assert_eq!(f32::ldexp(1f32, -111), f2);
-        assert_eq!(f32::ldexp(1.75f32, -12), f3);
-
-        assert_eq!(f32::ldexp(0f32, -123), 0f32);
-        assert_eq!(f32::ldexp(-0f32, -123), -0f32);
-
-        let inf: f32 = f32::INFINITY;
-        let neg_inf: f32 = f32::NEG_INFINITY;
-        let nan: f32 = f32::NAN;
-        assert_eq!(f32::ldexp(inf, -123), inf);
-        assert_eq!(f32::ldexp(neg_inf, -123), neg_inf);
-        assert!(f32::ldexp(nan, -123).is_nan());
-    }
-
-    #[test]
-    #[allow(deprecated)]
-    fn test_frexp() {
-        let f1 = 2.0f32.powi(-123);
-        let f2 = 2.0f32.powi(-111);
-        let f3 = 1.75 * 2.0f32.powi(-123);
-        let (x1, exp1) = f1.frexp();
-        let (x2, exp2) = f2.frexp();
-        let (x3, exp3) = f3.frexp();
-        assert_eq!((x1, exp1), (0.5f32, -122));
-        assert_eq!((x2, exp2), (0.5f32, -110));
-        assert_eq!((x3, exp3), (0.875f32, -122));
-        assert_eq!(f32::ldexp(x1, exp1), f1);
-        assert_eq!(f32::ldexp(x2, exp2), f2);
-        assert_eq!(f32::ldexp(x3, exp3), f3);
-
-        assert_eq!(0f32.frexp(), (0f32, 0));
-        assert_eq!((-0f32).frexp(), (-0f32, 0));
-    }
-
-    #[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;
-        let nan: f32 = f32::NAN;
-        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
-        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
-        assert!(match nan.frexp() { (x, _) => x.is_nan() })
-    }
-
-    #[test]
     fn test_asinh() {
         assert_eq!(0.0f32.asinh(), 0.0f32);
         assert_eq!((-0.0f32).asinh(), -0.0f32);
@@ -1868,4 +1728,31 @@ mod tests {
         assert_approx_eq!(ln_2, 2f32.ln());
         assert_approx_eq!(ln_10, 10f32.ln());
     }
+
+    #[test]
+    fn test_float_bits_conv() {
+        assert_eq!((1f32).to_bits(), 0x3f800000);
+        assert_eq!((12.5f32).to_bits(), 0x41480000);
+        assert_eq!((1337f32).to_bits(), 0x44a72000);
+        assert_eq!((-14.25f32).to_bits(), 0xc1640000);
+        assert_approx_eq!(f32::from_bits(0x3f800000), 1.0);
+        assert_approx_eq!(f32::from_bits(0x41480000), 12.5);
+        assert_approx_eq!(f32::from_bits(0x44a72000), 1337.0);
+        assert_approx_eq!(f32::from_bits(0xc1640000), -14.25);
+    }
+    #[test]
+    fn test_snan_masking() {
+        let snan: u32 = 0x7F801337;
+        const PAYLOAD_MASK: u32 = 0x003FFFFF;
+        const QNAN_MASK: u32  = 0x00400000;
+        let nan_masked_fl = f32::from_bits(snan);
+        let nan_masked = nan_masked_fl.to_bits();
+        // Ensure that signaling NaNs don't stay the same
+        assert_ne!(nan_masked, snan);
+        // Ensure that we have a quiet NaN
+        assert_ne!(nan_masked & QNAN_MASK, 0);
+        assert!(nan_masked_fl.is_nan());
+        // Ensure the payload wasn't touched during conversion
+        assert_eq!(nan_masked & PAYLOAD_MASK, snan & PAYLOAD_MASK);
+    }
 }
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index dd4bc253bed..82e3903eec7 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -8,7 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! The 64-bit floating point type.
+//! This module provides constants which are specific to the implementation
+//! of the `f64` floating point data type. Mathematically significant
+//! numbers are provided in the `consts` sub-module.
 //!
 //! *[See also the `f64` primitive type](../primitive.f64.html).*
 
@@ -20,8 +22,6 @@ use core::num;
 #[cfg(not(test))]
 use intrinsics;
 #[cfg(not(test))]
-use libc::c_int;
-#[cfg(not(test))]
 use num::FpCategory;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -186,36 +186,6 @@ impl f64 {
     #[inline]
     pub fn classify(self) -> FpCategory { num::Float::classify(self) }
 
-    /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
-    /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
-    /// The floating point encoding is documented in the [Reference][floating-point].
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// let num = 2.0f64;
-    ///
-    /// // (8388608, -22, 1)
-    /// let (mantissa, exponent, sign) = num.integer_decode();
-    /// let sign_f = sign as f64;
-    /// let mantissa_f = mantissa as f64;
-    /// let exponent_f = num.powf(exponent as f64);
-    ///
-    /// // 1 * 8388608 * 2^(-22) == 2
-    /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    /// [floating-point]: ../reference/types.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.
     ///
     /// ```
@@ -604,84 +574,6 @@ impl f64 {
     #[inline]
     pub fn to_radians(self) -> f64 { num::Float::to_radians(self) }
 
-    /// Constructs a floating point number of `x*2^exp`.
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// // 3*2^2 - 12 == 0
-    /// let abs_difference = (f64::ldexp(3.0, 2) - 12.0).abs();
-    ///
-    /// assert!(abs_difference < 1e-10);
-    /// ```
-    #[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) }
-    }
-
-    /// Breaks the number into a normalized fraction and a base-2 exponent,
-    /// satisfying:
-    ///
-    ///  * `self = x * 2^exp`
-    ///  * `0.5 <= abs(x) < 1.0`
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// let x = 4.0_f64;
-    ///
-    /// // (1/2)*2^3 -> 1 * 8/2 -> 4.0
-    /// let f = x.frexp();
-    /// let abs_difference_0 = (f.0 - 0.5).abs();
-    /// let abs_difference_1 = (f.1 as f64 - 3.0).abs();
-    ///
-    /// assert!(abs_difference_0 < 1e-10);
-    /// assert!(abs_difference_1 < 1e-10);
-    /// ```
-    #[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 {
-            let mut exp = 0;
-            let x = cmath::frexp(self, &mut exp);
-            (x, exp as isize)
-        }
-    }
-
-    /// Returns the next representable floating-point value in the direction of
-    /// `other`.
-    ///
-    /// ```
-    /// #![feature(float_extras)]
-    ///
-    /// let x = 1.0f64;
-    ///
-    /// 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) }
-    }
-
     /// Returns the maximum of the two numbers.
     ///
     /// ```
@@ -1116,6 +1008,68 @@ impl f64 {
             }
         }
     }
+
+    /// Raw transmutation to `u64`.
+    ///
+    /// Converts the `f64` into its raw memory representation,
+    /// similar to the `transmute` function.
+    ///
+    /// Note that this function is distinct from casting.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_bits_conv)]
+    /// assert!((1f64).to_bits() != 1f64 as u64); // to_bits() is not casting!
+    /// assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
+    ///
+    /// ```
+    #[unstable(feature = "float_bits_conv", reason = "recently added", issue = "40470")]
+    #[inline]
+    pub fn to_bits(self) -> u64 {
+        unsafe { ::mem::transmute(self) }
+    }
+
+    /// Raw transmutation from `u64`.
+    ///
+    /// Converts the given `u64` containing the float's raw memory
+    /// representation into the `f64` type, similar to the
+    /// `transmute` function.
+    ///
+    /// There is only one difference to a bare `transmute`:
+    /// Due to the implications onto Rust's safety promises being
+    /// uncertain, if the representation of a signaling NaN "sNaN" float
+    /// is passed to the function, the implementation is allowed to
+    /// return a quiet NaN instead.
+    ///
+    /// Note that this function is distinct from casting.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(float_bits_conv)]
+    /// use std::f64;
+    /// let v = f64::from_bits(0x4029000000000000);
+    /// let difference = (v - 12.5).abs();
+    /// assert!(difference <= 1e-5);
+    /// // Example for a signaling NaN value:
+    /// let snan = 0x7FF0000000000001;
+    /// assert_ne!(f64::from_bits(snan).to_bits(), snan);
+    /// ```
+    #[unstable(feature = "float_bits_conv", reason = "recently added", issue = "40470")]
+    #[inline]
+    pub fn from_bits(mut v: u64) -> Self {
+        const EXP_MASK: u64   = 0x7FF0000000000000;
+        const QNAN_MASK: u64  = 0x0001000000000000;
+        const FRACT_MASK: u64 = 0x000FFFFFFFFFFFFF;
+        if v & EXP_MASK == EXP_MASK && v & FRACT_MASK != 0 {
+            // If we have a NaN value, we
+            // convert signaling NaN values to quiet NaN
+            // by setting the the highest bit of the fraction
+            v |= QNAN_MASK;
+        }
+        unsafe { ::mem::transmute(v) }
+    }
 }
 
 #[cfg(test)]
@@ -1290,23 +1244,6 @@ mod tests {
     }
 
     #[test]
-    #[allow(deprecated)]
-    fn test_integer_decode() {
-        assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
-        assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
-        assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
-        assert_eq!(0f64.integer_decode(), (0, -1075, 1));
-        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));
-
-        // 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]
     fn test_floor() {
         assert_approx_eq!(1.0f64.floor(), 1.0f64);
         assert_approx_eq!(1.3f64.floor(), 1.0f64);
@@ -1618,58 +1555,6 @@ mod tests {
     }
 
     #[test]
-    #[allow(deprecated)]
-    fn test_ldexp() {
-        let f1 = 2.0f64.powi(-123);
-        let f2 = 2.0f64.powi(-111);
-        let f3 = 1.75 * 2.0f64.powi(-12);
-        assert_eq!(f64::ldexp(1f64, -123), f1);
-        assert_eq!(f64::ldexp(1f64, -111), f2);
-        assert_eq!(f64::ldexp(1.75f64, -12), f3);
-
-        assert_eq!(f64::ldexp(0f64, -123), 0f64);
-        assert_eq!(f64::ldexp(-0f64, -123), -0f64);
-
-        let inf: f64 = INFINITY;
-        let neg_inf: f64 = NEG_INFINITY;
-        let nan: f64 = NAN;
-        assert_eq!(f64::ldexp(inf, -123), inf);
-        assert_eq!(f64::ldexp(neg_inf, -123), neg_inf);
-        assert!(f64::ldexp(nan, -123).is_nan());
-    }
-
-    #[test]
-    #[allow(deprecated)]
-    fn test_frexp() {
-        let f1 = 2.0f64.powi(-123);
-        let f2 = 2.0f64.powi(-111);
-        let f3 = 1.75 * 2.0f64.powi(-123);
-        let (x1, exp1) = f1.frexp();
-        let (x2, exp2) = f2.frexp();
-        let (x3, exp3) = f3.frexp();
-        assert_eq!((x1, exp1), (0.5f64, -122));
-        assert_eq!((x2, exp2), (0.5f64, -110));
-        assert_eq!((x3, exp3), (0.875f64, -122));
-        assert_eq!(f64::ldexp(x1, exp1), f1);
-        assert_eq!(f64::ldexp(x2, exp2), f2);
-        assert_eq!(f64::ldexp(x3, exp3), f3);
-
-        assert_eq!(0f64.frexp(), (0f64, 0));
-        assert_eq!((-0f64).frexp(), (-0f64, 0));
-    }
-
-    #[test] #[cfg_attr(windows, ignore)] // FIXME #8755
-    #[allow(deprecated)]
-    fn test_frexp_nowin() {
-        let inf: f64 = INFINITY;
-        let neg_inf: f64 = NEG_INFINITY;
-        let nan: f64 = NAN;
-        assert_eq!(match inf.frexp() { (x, _) => x }, inf);
-        assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
-        assert!(match nan.frexp() { (x, _) => x.is_nan() })
-    }
-
-    #[test]
     fn test_asinh() {
         assert_eq!(0.0f64.asinh(), 0.0f64);
         assert_eq!((-0.0f64).asinh(), -0.0f64);
@@ -1753,4 +1638,16 @@ mod tests {
         assert_approx_eq!(ln_2, 2f64.ln());
         assert_approx_eq!(ln_10, 10f64.ln());
     }
+
+    #[test]
+    fn test_float_bits_conv() {
+        assert_eq!((1f64).to_bits(), 0x3ff0000000000000);
+        assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
+        assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
+        assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
+        assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0);
+        assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5);
+        assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
+        assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
+    }
 }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index bfb0aa6e1a1..1167c39dba8 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -23,19 +23,19 @@ use ptr;
 use slice;
 use str::{self, Utf8Error};
 
-/// A type representing an owned C-compatible string
+/// A type representing an owned C-compatible string.
 ///
 /// This type serves the primary purpose of being able to safely generate a
 /// C-compatible string from a Rust byte slice or vector. An instance of this
 /// type is a static guarantee that the underlying bytes contain no interior 0
 /// bytes and the final byte is 0.
 ///
-/// A `CString` is created from either a byte slice or a byte vector. After
-/// being created, a `CString` predominately inherits all of its methods from
-/// the `Deref` implementation to `[c_char]`. Note that the underlying array
-/// is represented as an array of `c_char` as opposed to `u8`. A `u8` slice
-/// can be obtained with the `as_bytes` method.  Slices produced from a `CString`
-/// do *not* contain the trailing nul terminator unless otherwise specified.
+/// A `CString` is created from either a byte slice or a byte vector. A [`u8`]
+/// slice can be obtained with the `as_bytes` method. Slices produced from a
+/// `CString` do *not* contain the trailing nul terminator unless otherwise
+/// specified.
+///
+/// [`u8`]: ../primitive.u8.html
 ///
 /// # Examples
 ///
@@ -83,12 +83,14 @@ pub struct CString {
 ///
 /// Note that this structure is **not** `repr(C)` and is not recommended to be
 /// placed in the signatures of FFI functions. Instead safe wrappers of FFI
-/// functions may leverage the unsafe `from_ptr` constructor to provide a safe
+/// functions may leverage the unsafe [`from_ptr`] constructor to provide a safe
 /// interface to other consumers.
 ///
+/// [`from_ptr`]: #method.from_ptr
+///
 /// # Examples
 ///
-/// Inspecting a foreign C string
+/// Inspecting a foreign C string:
 ///
 /// ```no_run
 /// use std::ffi::CStr;
@@ -102,7 +104,7 @@ pub struct CString {
 /// }
 /// ```
 ///
-/// Passing a Rust-originating C string
+/// Passing a Rust-originating C string:
 ///
 /// ```no_run
 /// use std::ffi::{CString, CStr};
@@ -118,7 +120,9 @@ pub struct CString {
 /// work(&s);
 /// ```
 ///
-/// Converting a foreign C string into a Rust `String`
+/// Converting a foreign C string into a Rust [`String`]:
+///
+/// [`String`]: ../string/struct.String.html
 ///
 /// ```no_run
 /// use std::ffi::CStr;
@@ -144,14 +148,18 @@ pub struct CStr {
     inner: [c_char]
 }
 
-/// An error returned from `CString::new` to indicate that a nul byte was found
+/// An error returned from [`CString::new`] to indicate that a nul byte was found
 /// in the vector provided.
+///
+/// [`CString::new`]: struct.CString.html#method.new
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[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
+/// 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.
+///
+/// [`CStr::from_bytes_with_nul`]: struct.CStr.html#method.from_bytes_with_nul
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
 pub struct FromBytesWithNulError {
@@ -177,8 +185,10 @@ impl FromBytesWithNulError {
     }
 }
 
-/// An error returned from `CString::into_string` to indicate that a UTF-8 error
+/// An error returned from [`CString::into_string`] to indicate that a UTF-8 error
 /// was encountered during the conversion.
+///
+/// [`CString::into_string`]: struct.CString.html#method.into_string
 #[derive(Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "cstring_into", since = "1.7.0")]
 pub struct IntoStringError {
@@ -226,10 +236,12 @@ impl CString {
     /// Creates a C-compatible string from a byte vector without checking for
     /// interior 0 bytes.
     ///
-    /// This method is equivalent to `new` except that no runtime assertion
+    /// This method is equivalent to [`new`] except that no runtime assertion
     /// is made that `v` contains no 0 bytes, and it requires an actual
     /// byte vector, not anything that can be converted to one with Into.
     ///
+    /// [`new`]: #method.new
+    ///
     /// # Examples
     ///
     /// ```
@@ -254,9 +266,11 @@ impl CString {
     /// # Safety
     ///
     /// This should only ever be called with a pointer that was earlier
-    /// obtained by calling `into_raw` on a `CString`. Other usage (e.g. trying to take
+    /// obtained by calling [`into_raw`] on a `CString`. Other usage (e.g. trying to take
     /// ownership of a string that was allocated by foreign code) is likely to lead
     /// to undefined behavior or allocator corruption.
+    ///
+    /// [`into_raw`]: #method.into_raw
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub unsafe fn from_raw(ptr: *mut c_char) -> CString {
         let len = libc::strlen(ptr) + 1; // Including the NUL byte
@@ -267,19 +281,23 @@ impl CString {
     /// Transfers ownership of the string to a C caller.
     ///
     /// The pointer must be returned to Rust and reconstituted using
-    /// `from_raw` to be properly deallocated. Specifically, one
+    /// [`from_raw`] to be properly deallocated. Specifically, one
     /// should *not* use the standard C `free` function to deallocate
     /// this string.
     ///
-    /// Failure to call `from_raw` will lead to a memory leak.
+    /// Failure to call [`from_raw`] will lead to a memory leak.
+    ///
+    /// [`from_raw`]: #method.from_raw
     #[stable(feature = "cstr_memory", since = "1.4.0")]
     pub fn into_raw(self) -> *mut c_char {
         Box::into_raw(self.into_inner()) as *mut c_char
     }
 
-    /// Converts the `CString` into a `String` if it contains valid Unicode data.
+    /// Converts the `CString` into a [`String`] if it contains valid Unicode data.
     ///
     /// On failure, ownership of the original `CString` is returned.
+    ///
+    /// [`String`]: ../string/struct.String.html
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_string(self) -> Result<String, IntoStringError> {
         String::from_utf8(self.into_bytes())
@@ -301,8 +319,10 @@ impl CString {
         vec
     }
 
-    /// Equivalent to the `into_bytes` function except that the returned vector
+    /// Equivalent to the [`into_bytes`] function except that the returned vector
     /// includes the trailing nul byte.
+    ///
+    /// [`into_bytes`]: #method.into_bytes
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_bytes_with_nul(self) -> Vec<u8> {
         self.into_inner().into_vec()
@@ -317,20 +337,34 @@ impl CString {
         &self.inner[..self.inner.len() - 1]
     }
 
-    /// Equivalent to the `as_bytes` function except that the returned slice
+    /// Equivalent to the [`as_bytes`] function except that the returned slice
     /// includes the trailing nul byte.
+    ///
+    /// [`as_bytes`]: #method.as_bytes
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_bytes_with_nul(&self) -> &[u8] {
         &self.inner
     }
 
-    /// Converts this `CString` into a boxed `CStr`.
-    #[unstable(feature = "into_boxed_c_str", issue = "0")]
+    /// Extracts a [`CStr`] slice containing the entire string.
+    ///
+    /// [`CStr`]: struct.CStr.html
+    #[unstable(feature = "as_c_str", issue = "40380")]
+    pub fn as_c_str(&self) -> &CStr {
+        &*self
+    }
+
+    /// Converts this `CString` into a boxed [`CStr`].
+    ///
+    /// [`CStr`]: struct.CStr.html
+    #[unstable(feature = "into_boxed_c_str", issue = "40380")]
     pub fn into_boxed_c_str(self) -> Box<CStr> {
         unsafe { mem::transmute(self.into_inner()) }
     }
 
-    // Bypass "move out of struct which implements `Drop` trait" restriction.
+    // Bypass "move out of struct which implements [`Drop`] trait" restriction.
+    ///
+    /// [`Drop`]: ../ops/trait.Drop.html
     fn into_inner(self) -> Box<[u8]> {
         unsafe {
             let result = ptr::read(&self.inner);
@@ -356,7 +390,7 @@ impl ops::Deref for CString {
     type Target = CStr;
 
     fn deref(&self) -> &CStr {
-        unsafe { mem::transmute(self.as_bytes_with_nul()) }
+        unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) }
     }
 }
 
@@ -415,6 +449,20 @@ impl<'a> From<&'a CStr> for Box<CStr> {
     }
 }
 
+#[stable(feature = "c_string_from_box", since = "1.18.0")]
+impl From<Box<CStr>> for CString {
+    fn from(s: Box<CStr>) -> CString {
+        s.into_c_string()
+    }
+}
+
+#[stable(feature = "box_from_c_string", since = "1.18.0")]
+impl Into<Box<CStr>> for CString {
+    fn into(self) -> Box<CStr> {
+        self.into_boxed_c_str()
+    }
+}
+
 #[stable(feature = "default_box_extra", since = "1.17.0")]
 impl Default for Box<CStr> {
     fn default() -> Box<CStr> {
@@ -425,7 +473,9 @@ impl Default for Box<CStr> {
 
 impl NulError {
     /// Returns the position of the nul byte in the slice that was provided to
-    /// `CString::new`.
+    /// [`CString::new`].
+    ///
+    /// [`CString::new`]: struct.CString.html#method.new
     ///
     /// # Examples
     ///
@@ -500,8 +550,10 @@ impl fmt::Display for FromBytesWithNulError {
 }
 
 impl IntoStringError {
-    /// Consumes this error, returning original `CString` which generated the
+    /// Consumes this error, returning original [`CString`] which generated the
     /// error.
+    ///
+    /// [`CString`]: struct.CString.html
     #[stable(feature = "cstring_into", since = "1.7.0")]
     pub fn into_cstring(self) -> CString {
         self.inner
@@ -539,9 +591,9 @@ impl CStr {
     /// allows inspection and interoperation of non-owned C strings. This method
     /// is unsafe for a number of reasons:
     ///
-    /// * There is no guarantee to the validity of `ptr`
+    /// * There is no guarantee to the validity of `ptr`.
     /// * The returned lifetime is not guaranteed to be the actual lifetime of
-    ///   `ptr`
+    ///   `ptr`.
     /// * There is no guarantee that the memory pointed to by `ptr` contains a
     ///   valid nul terminator byte at the end of the string.
     ///
@@ -569,7 +621,8 @@ impl CStr {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
         let len = libc::strlen(ptr);
-        mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
+        let ptr = ptr as *const u8;
+        CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
     }
 
     /// Creates a C string wrapper from a byte slice.
@@ -684,26 +737,30 @@ impl CStr {
 
     /// Converts this C string to a byte slice containing the trailing 0 byte.
     ///
-    /// This function is the equivalent of `to_bytes` except that it will retain
+    /// This function is the equivalent of [`to_bytes`] except that it will retain
     /// the trailing nul instead of chopping it off.
     ///
     /// > **Note**: This method is currently implemented as a 0-cost cast, but
     /// > it is planned to alter its definition in the future to perform the
     /// > length calculation whenever this method is called.
+    ///
+    /// [`to_bytes`]: #method.to_bytes
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_bytes_with_nul(&self) -> &[u8] {
         unsafe { mem::transmute(&self.inner) }
     }
 
-    /// Yields a `&str` slice if the `CStr` contains valid UTF-8.
+    /// Yields a [`&str`] slice if the `CStr` contains valid UTF-8.
     ///
     /// This function will calculate the length of this string and check for
-    /// UTF-8 validity, and then return the `&str` if it's valid.
+    /// UTF-8 validity, and then return the [`&str`] if it's valid.
     ///
     /// > **Note**: This method is currently implemented to check for validity
     /// > after a 0-cost cast, but it is planned to alter its definition in the
     /// > future to perform the length calculation in addition to the UTF-8
     /// > check whenever this method is called.
+    ///
+    /// [`&str`]: ../primitive.str.html
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
         // NB: When CStr is changed to perform the length check in .to_bytes()
@@ -713,21 +770,33 @@ impl CStr {
         str::from_utf8(self.to_bytes())
     }
 
-    /// Converts a `CStr` into a `Cow<str>`.
+    /// Converts a `CStr` into a [`Cow`]`<`[`str`]`>`.
     ///
     /// This function will calculate the length of this string (which normally
     /// requires a linear amount of work to be done) and then return the
-    /// resulting slice as a `Cow<str>`, replacing any invalid UTF-8 sequences
+    /// resulting slice as a [`Cow`]`<`[`str`]`>`, replacing any invalid UTF-8 sequences
     /// with `U+FFFD REPLACEMENT CHARACTER`.
     ///
     /// > **Note**: This method is currently implemented to check for validity
     /// > after a 0-cost cast, but it is planned to alter its definition in the
     /// > future to perform the length calculation in addition to the UTF-8
     /// > check whenever this method is called.
+    ///
+    /// [`Cow`]: ../borrow/enum.Cow.html
+    /// [`str`]: ../primitive.str.html
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
         String::from_utf8_lossy(self.to_bytes())
     }
+
+    /// Converts a [`Box`]`<CStr>` into a [`CString`] without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`CString`]: struct.CString.html
+    #[unstable(feature = "into_boxed_c_str", issue = "40380")]
+    pub fn into_c_string(self: Box<CStr>) -> CString {
+        unsafe { mem::transmute(self) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -922,12 +991,11 @@ mod tests {
     fn into_boxed() {
         let orig: &[u8] = b"Hello, world!\0";
         let cstr = CStr::from_bytes_with_nul(orig).unwrap();
-        let cstring = cstr.to_owned();
-        let box1: Box<CStr> = Box::from(cstr);
-        let box2 = cstring.into_boxed_c_str();
-        assert_eq!(cstr, &*box1);
-        assert_eq!(box1, box2);
-        assert_eq!(&*box2, cstr);
+        let boxed: Box<CStr> = Box::from(cstr);
+        let cstring = cstr.to_owned().into_boxed_c_str().into_c_string();
+        assert_eq!(cstr, &*boxed);
+        assert_eq!(&*boxed, &*cstring);
+        assert_eq!(&*cstring, cstr);
     }
 
     #[test]
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 41bdd9c51d4..a5a1b5e5f09 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -188,6 +188,16 @@ impl OsString {
     /// in the given `OsString`.
     ///
     /// The collection may reserve more space to avoid frequent reallocations.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsString;
+    ///
+    /// let mut s = OsString::new();
+    /// s.reserve(10);
+    /// assert!(s.capacity() >= 10);
+    /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
     pub fn reserve(&mut self, additional: usize) {
         self.inner.reserve(additional)
@@ -200,19 +210,59 @@ impl OsString {
     /// Note that the allocator may give the collection more space than it
     /// requests. Therefore capacity can not be relied upon to be precisely
     /// minimal. Prefer reserve if future insertions are expected.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsString;
+    ///
+    /// let mut s = OsString::new();
+    /// s.reserve_exact(10);
+    /// assert!(s.capacity() >= 10);
+    /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]
     pub fn reserve_exact(&mut self, additional: usize) {
         self.inner.reserve_exact(additional)
     }
 
     /// Shrinks the capacity of the `OsString` to match its length.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(osstring_shrink_to_fit)]
+    ///
+    /// use std::ffi::OsString;
+    ///
+    /// let mut s = OsString::from("foo");
+    ///
+    /// s.reserve(100);
+    /// assert!(s.capacity() >= 100);
+    ///
+    /// s.shrink_to_fit();
+    /// assert_eq!(3, s.capacity());
+    /// ```
     #[unstable(feature = "osstring_shrink_to_fit", issue = "40421")]
     pub fn shrink_to_fit(&mut self) {
         self.inner.shrink_to_fit()
     }
 
-    /// Converts this `OsString` into a boxed `OsStr`.
-    #[unstable(feature = "into_boxed_os_str", issue = "0")]
+    /// Converts this `OsString` into a boxed [`OsStr`].
+    ///
+    /// [`OsStr`]: struct.OsStr.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(into_boxed_os_str)]
+    ///
+    /// use std::ffi::{OsString, OsStr};
+    ///
+    /// let s = OsString::from("hello");
+    ///
+    /// let b: Box<OsStr> = s.into_boxed_os_str();
+    /// ```
+    #[unstable(feature = "into_boxed_os_str", issue = "40380")]
     pub fn into_boxed_os_str(self) -> Box<OsStr> {
         unsafe { mem::transmute(self.inner.into_box()) }
     }
@@ -398,6 +448,16 @@ impl OsStr {
     /// Copies the slice into an owned [`OsString`].
     ///
     /// [`OsString`]: struct.OsString.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::{OsStr, OsString};
+    ///
+    /// let os_str = OsStr::new("foo");
+    /// let os_string = os_str.to_os_string();
+    /// assert_eq!(os_string, OsString::from("foo"));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_os_string(&self) -> OsString {
         OsString { inner: self.inner.to_owned() }
@@ -424,12 +484,13 @@ impl OsStr {
     /// Returns the length of this `OsStr`.
     ///
     /// Note that this does **not** return the number of bytes in this string
-    /// as, for example, OS strings on Windows are encoded as a list of `u16`
+    /// as, for example, OS strings on Windows are encoded as a list of [`u16`]
     /// rather than a list of bytes. This number is simply useful for passing to
     /// other methods like [`OsString::with_capacity`] to avoid reallocations.
     ///
     /// See `OsStr` introduction for more information about encoding.
     ///
+    /// [`u16`]: ../primitive.u16.html
     /// [`OsString::with_capacity`]: struct.OsString.html#method.with_capacity
     ///
     /// # Examples
@@ -448,6 +509,16 @@ impl OsStr {
         self.inner.inner.len()
     }
 
+    /// Converts a [`Box`]`<OsStr>` into an [`OsString`] without copying or allocating.
+    ///
+    /// [`Box`]: ../boxed/struct.Box.html
+    /// [`OsString`]: struct.OsString.html
+    #[unstable(feature = "into_boxed_os_str", issue = "40380")]
+    pub fn into_os_string(self: Box<OsStr>) -> OsString {
+        let inner: Box<Slice> = unsafe { mem::transmute(self) };
+        OsString { inner: Buf::from_box(inner) }
+    }
+
     /// Gets the underlying byte representation.
     ///
     /// Note: it is *crucial* that this API is private, to avoid
@@ -464,6 +535,20 @@ impl<'a> From<&'a OsStr> for Box<OsStr> {
     }
 }
 
+#[stable(feature = "os_string_from_box", since = "1.18.0")]
+impl From<Box<OsStr>> for OsString {
+    fn from(boxed: Box<OsStr>) -> OsString {
+        boxed.into_os_string()
+    }
+}
+
+#[stable(feature = "box_from_os_string", since = "1.18.0")]
+impl Into<Box<OsStr>> for OsString {
+    fn into(self) -> Box<OsStr> {
+        self.into_boxed_os_str()
+    }
+}
+
 #[stable(feature = "box_default_extra", since = "1.17.0")]
 impl Default for Box<OsStr> {
     fn default() -> Box<OsStr> {
@@ -598,7 +683,13 @@ impl Borrow<OsStr> for OsString {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl ToOwned for OsStr {
     type Owned = OsString;
-    fn to_owned(&self) -> OsString { self.to_os_string() }
+    fn to_owned(&self) -> OsString {
+        self.to_os_string()
+    }
+    fn clone_into(&self, target: &mut OsString) {
+        target.clear();
+        target.push(self);
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -772,12 +863,11 @@ mod tests {
     fn into_boxed() {
         let orig = "Hello, world!";
         let os_str = OsStr::new(orig);
-        let os_string = os_str.to_owned();
-        let box1: Box<OsStr> = Box::from(os_str);
-        let box2 = os_string.into_boxed_os_str();
-        assert_eq!(os_str, &*box1);
-        assert_eq!(box1, box2);
-        assert_eq!(&*box2, os_str);
+        let boxed: Box<OsStr> = Box::from(os_str);
+        let os_string = os_str.to_owned().into_boxed_os_str().into_os_string();
+        assert_eq!(os_str, &*boxed);
+        assert_eq!(&*boxed, &*os_string);
+        assert_eq!(&*os_string, os_str);
     }
 
     #[test]
@@ -785,4 +875,14 @@ mod tests {
         let boxed = <Box<OsStr>>::default();
         assert!(boxed.is_empty());
     }
+
+    #[test]
+    fn test_os_str_clone_into() {
+        let mut os_string = OsString::with_capacity(123);
+        os_string.push("hello");
+        let os_str = OsStr::new("bonjour");
+        os_str.clone_into(&mut os_string);
+        assert_eq!(os_str, os_string);
+        assert!(os_string.capacity() >= 123);
+    }
 }
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index e5562d05f10..69843199348 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -142,14 +142,14 @@ pub struct DirEntry(fs_imp::DirEntry);
 /// [`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()`],
+/// 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
+/// [`new`]: struct.OpenOptions.html#method.new
+/// [`open`]: struct.OpenOptions.html#method.open
 /// [result]: ../io/type.Result.html
 /// [file]: struct.File.html
 ///
@@ -1176,6 +1176,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 /// This function currently corresponds to the `unlink` function on Unix
 /// and the `DeleteFile` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1212,6 +1213,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// This function currently corresponds to the `stat` function on Unix
 /// and the `GetFileAttributesEx` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1245,6 +1247,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 /// This function currently corresponds to the `lstat` function on Unix
 /// and the `GetFileAttributesEx` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1287,6 +1290,7 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
 /// on Windows, `from` can be anything, but `to` must *not* be a directory.
 ///
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1330,6 +1334,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// `O_CLOEXEC` is set for returned file descriptors.
 /// On Windows, this function currently corresponds to `CopyFileEx`.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1366,6 +1371,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
 /// This function currently corresponds to the `link` function on Unix
 /// and the `CreateHardLink` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1424,6 +1430,7 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
 /// and the `CreateFile` function with `FILE_FLAG_OPEN_REPARSE_POINT` and
 /// `FILE_FLAG_BACKUP_SEMANTICS` flags on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1457,6 +1464,7 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 /// This function currently corresponds to the `realpath` function on Unix
 /// and the `CreateFile` and `GetFinalPathNameByHandle` functions on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1489,6 +1497,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
 /// This function currently corresponds to the `mkdir` function on Unix
 /// and the `CreateDirectory` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1522,6 +1531,7 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// This function currently corresponds to the `mkdir` function on Unix
 /// and the `CreateDirectory` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1534,6 +1544,12 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// error conditions for when a directory is being created (after it is
 /// determined to not exist) are outlined by `fs::create_dir`.
 ///
+/// Notable exception is made for situations where any of the directories
+/// specified in the `path` could not be created as it was being created concurrently.
+/// Such cases are considered success. In other words: calling `create_dir_all`
+/// concurrently from multiple threads or processes is guaranteed to not fail
+/// due to race itself.
+///
 /// # Examples
 ///
 /// ```
@@ -1556,6 +1572,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// This function currently corresponds to the `rmdir` function on Unix
 /// and the `RemoveDirectory` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1593,6 +1610,7 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// and the `FindFirstFile`, `GetFileAttributesEx`, `DeleteFile`, and `RemoveDirectory` functions
 /// on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1627,6 +1645,7 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// This function currently corresponds to the `opendir` function on Unix
 /// and the `FindFirstFile` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1673,6 +1692,7 @@ pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
 /// This function currently corresponds to the `chmod` function on Unix
 /// and the `SetFileAttributes` function on Windows.
 /// Note that, this [may change in the future][changes].
+///
 /// [changes]: ../io/index.html#platform-specific-behavior
 ///
 /// # Errors
@@ -1720,9 +1740,9 @@ impl DirBuilder {
         }
     }
 
-    /// Indicate that directories create should be created recursively, creating
-    /// all parent directories if they do not exist with the same security and
-    /// permissions settings.
+    /// Indicates that directories should be created recursively, creating all
+    /// parent directories. Parents that do not exist are created with the same
+    /// security and permissions settings.
     ///
     /// This option defaults to `false`.
     ///
@@ -1743,6 +1763,9 @@ impl DirBuilder {
     /// Create the specified directory with the options configured in this
     /// builder.
     ///
+    /// It is considered an error if the directory already exists unless
+    /// recursive mode is enabled.
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -1769,11 +1792,25 @@ impl DirBuilder {
     }
 
     fn create_dir_all(&self, path: &Path) -> io::Result<()> {
-        if path == Path::new("") || path.is_dir() { return Ok(()) }
-        if let Some(p) = path.parent() {
-            self.create_dir_all(p)?
+        if path == Path::new("") {
+            return Ok(())
+        }
+
+        match self.inner.mkdir(path) {
+            Ok(()) => return Ok(()),
+            Err(ref e) if e.kind() == io::ErrorKind::NotFound => {}
+            Err(_) if path.is_dir() => return Ok(()),
+            Err(e) => return Err(e),
+        }
+        match path.parent() {
+            Some(p) => try!(self.create_dir_all(p)),
+            None => return Err(io::Error::new(io::ErrorKind::Other, "failed to create whole tree")),
+        }
+        match self.inner.mkdir(path) {
+            Ok(()) => Ok(()),
+            Err(_) if path.is_dir() => Ok(()),
+            Err(e) => Err(e),
         }
-        self.inner.mkdir(path)
     }
 }
 
@@ -1793,6 +1830,7 @@ mod tests {
     use rand::{StdRng, Rng};
     use str;
     use sys_common::io::test::{TempDir, tmpdir};
+    use thread;
 
     #[cfg(windows)]
     use os::windows::fs::{symlink_dir, symlink_file};
@@ -2261,11 +2299,42 @@ mod tests {
     }
 
     #[test]
+    fn concurrent_recursive_mkdir() {
+        for _ in 0..100 {
+            let dir = tmpdir();
+            let mut dir = dir.join("a");
+            for _ in 0..40 {
+                dir = dir.join("a");
+            }
+            let mut join = vec!();
+            for _ in 0..8 {
+                let dir = dir.clone();
+                join.push(thread::spawn(move || {
+                    check!(fs::create_dir_all(&dir));
+                }))
+            }
+
+            // No `Display` on result of `join()`
+            join.drain(..).map(|join| join.join().unwrap()).count();
+        }
+    }
+
+    #[test]
     fn recursive_mkdir_slash() {
         check!(fs::create_dir_all(&Path::new("/")));
     }
 
     #[test]
+    fn recursive_mkdir_dot() {
+        check!(fs::create_dir_all(&Path::new(".")));
+    }
+
+    #[test]
+    fn recursive_mkdir_empty() {
+        check!(fs::create_dir_all(&Path::new("")));
+    }
+
+    #[test]
     fn recursive_rmdir() {
         let tmpdir = tmpdir();
         let d1 = tmpdir.join("d1");
@@ -2343,7 +2412,7 @@ mod tests {
 
         let tmpdir = tmpdir();
         let unicode = tmpdir.path();
-        let unicode = unicode.join(&format!("test-각丁ー再见"));
+        let unicode = unicode.join("test-각丁ー再见");
         check!(fs::create_dir(&unicode));
         assert!(unicode.exists());
         assert!(!Path::new("test/unicode-bogus-path-각丁ー再见").exists());
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index f98a3a87b01..3b82412716e 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -21,12 +21,12 @@ use memchr;
 /// The `BufReader` struct adds buffering to any reader.
 ///
 /// It can be excessively inefficient to work directly with a [`Read`] instance.
-/// For example, every call to [`read`] on [`TcpStream`] results in a system call.
-/// A `BufReader` performs large, infrequent reads on the underlying [`Read`]
-/// and maintains an in-memory buffer of the results.
+/// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
+/// results in a system call. A `BufReader` performs large, infrequent reads on
+/// the underlying [`Read`] and maintains an in-memory buffer of the results.
 ///
 /// [`Read`]: ../../std/io/trait.Read.html
-/// [`read`]: ../../std/net/struct.TcpStream.html#method.read
+/// [`TcpStream::read`]: ../../std/net/struct.TcpStream.html#method.read
 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
 ///
 /// # Examples
@@ -261,9 +261,10 @@ impl<R: Seek> Seek for BufReader<R> {
 /// Wraps a writer and buffers its output.
 ///
 /// It can be excessively inefficient to work directly with something that
-/// implements [`Write`]. For example, every call to [`write`] on [`TcpStream`]
-/// results in a system call. A `BufWriter` keeps an in-memory buffer of data
-/// and writes it to an underlying writer in large, infrequent batches.
+/// implements [`Write`]. For example, every call to
+/// [`write`][`Tcpstream::write`] on [`TcpStream`] results in a system call. A
+/// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
+/// writer in large, infrequent batches.
 ///
 /// The buffer will be written out when the writer is dropped.
 ///
@@ -303,7 +304,7 @@ impl<R: Seek> Seek for BufReader<R> {
 /// the `stream` is dropped.
 ///
 /// [`Write`]: ../../std/io/trait.Write.html
-/// [`write`]: ../../std/net/struct.TcpStream.html#method.write
+/// [`Tcpstream::write`]: ../../std/net/struct.TcpStream.html#method.write
 /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct BufWriter<W: Write> {
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 60767ea4786..53347eb14db 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -89,6 +89,10 @@ pub struct Cursor<T> {
 impl<T> Cursor<T> {
     /// Creates a new cursor wrapping the provided underlying I/O object.
     ///
+    /// Cursor initial position is `0` even if underlying object (e.
+    /// g. `Vec`) is not empty. So writing to cursor starts with
+    /// overwriting `Vec` content, not with appending to it.
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index 6d4da2e6a88..fb67eaf3c63 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -140,13 +140,13 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     TimedOut,
     /// An error returned when an operation could not be completed because a
-    /// call to [`write()`] returned [`Ok(0)`].
+    /// call to [`write`] returned [`Ok(0)`].
     ///
     /// This typically means that an operation could only succeed if it wrote a
     /// particular number of bytes but only a smaller number of bytes could be
     /// written.
     ///
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     /// [`Ok(0)`]: ../../std/io/type.Result.html
     #[stable(feature = "rust1", since = "1.0.0")]
     WriteZero,
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 58788cdcd4c..c872a8e5261 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -21,7 +21,8 @@
 //! of other types, and you can implement them for your types too. As such,
 //! you'll see a few different types of I/O throughout the documentation in
 //! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For
-//! example, [`Read`] adds a [`read()`] method, which we can use on `File`s:
+//! example, [`Read`] adds a [`read`][`Read::read`] method, which we can use on
+//! `File`s:
 //!
 //! ```
 //! use std::io;
@@ -106,7 +107,7 @@
 //! ```
 //!
 //! [`BufWriter`] doesn't add any new ways of writing; it just buffers every call
-//! to [`write()`]:
+//! to [`write`][`Write::write`]:
 //!
 //! ```
 //! use std::io;
@@ -145,6 +146,18 @@
 //! # }
 //! ```
 //!
+//! Note that you cannot use the `?` operator in functions that do not return
+//! a `Result<T, E>` (e.g. `main`). Instead, you can call `.unwrap()` or `match`
+//! on the return value to catch any possible errors:
+//!
+//! ```
+//! use std::io;
+//!
+//! let mut input = String::new();
+//!
+//! io::stdin().read_line(&mut input).unwrap();
+//! ```
+//!
 //! And a very common source of output is standard output:
 //!
 //! ```
@@ -157,7 +170,7 @@
 //! # }
 //! ```
 //!
-//! Of course, using [`io::stdout()`] directly is less common than something like
+//! Of course, using [`io::stdout`] directly is less common than something like
 //! [`println!`].
 //!
 //! ## Iterator types
@@ -245,13 +258,13 @@
 //! [`Vec<T>`]: ../vec/struct.Vec.html
 //! [`BufReader`]: struct.BufReader.html
 //! [`BufWriter`]: struct.BufWriter.html
-//! [`write()`]: trait.Write.html#tymethod.write
-//! [`io::stdout()`]: fn.stdout.html
+//! [`Write::write`]: trait.Write.html#tymethod.write
+//! [`io::stdout`]: fn.stdout.html
 //! [`println!`]: ../macro.println.html
 //! [`Lines`]: struct.Lines.html
 //! [`io::Result`]: type.Result.html
 //! [`?` operator]: ../../book/syntax-index.html
-//! [`read()`]: trait.Read.html#tymethod.read
+//! [`Read::read`]: trait.Read.html#tymethod.read
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -274,9 +287,11 @@ pub use self::error::{Result, Error, ErrorKind};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
+pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
+#[unstable(feature = "print_internals", issue = "0")]
+pub use self::stdio::{_print, _eprint};
 #[unstable(feature = "libstd_io_internals", issue = "0")]
 #[doc(no_inline, hidden)]
 pub use self::stdio::{set_panic, set_print};
@@ -453,6 +468,9 @@ pub trait Read {
     /// variant will be returned. If an error is returned then it must be
     /// guaranteed that no bytes were read.
     ///
+    /// An error of the `ErrorKind::Interrupted` kind is non-fatal and the read
+    /// operation should be retried if there is nothing else to do.
+    ///
     /// # Examples
     ///
     /// [`File`][file]s implement `Read`:
@@ -468,7 +486,7 @@ pub trait Read {
     /// let mut f = File::open("foo.txt")?;
     /// let mut buffer = [0; 10];
     ///
-    /// // read 10 bytes
+    /// // read up to 10 bytes
     /// f.read(&mut buffer[..])?;
     /// # Ok(())
     /// # }
@@ -530,7 +548,7 @@ pub trait Read {
     /// If the data in this stream is *not* valid UTF-8 then an error is
     /// returned and `buf` is unchanged.
     ///
-    /// See [`read_to_end()`][readtoend] for other error semantics.
+    /// See [`read_to_end`][readtoend] for other error semantics.
     ///
     /// [readtoend]: #method.read_to_end
     ///
@@ -815,12 +833,12 @@ pub trait Read {
 ///
 /// Implementors of the `Write` trait are sometimes called 'writers'.
 ///
-/// Writers are defined by two required methods, [`write()`] and [`flush()`]:
+/// Writers are defined by two required methods, [`write`] and [`flush`]:
 ///
-/// * The [`write()`] method will attempt to write some data into the object,
+/// * The [`write`] method will attempt to write some data into the object,
 ///   returning how many bytes were successfully written.
 ///
-/// * The [`flush()`] method is useful for adaptors and explicit buffers
+/// * The [`flush`] method is useful for adaptors and explicit buffers
 ///   themselves for ensuring that all buffered data has been pushed out to the
 ///   'true sink'.
 ///
@@ -828,8 +846,8 @@ pub trait Read {
 /// throughout [`std::io`] take and provide types which implement the `Write`
 /// trait.
 ///
-/// [`write()`]: #tymethod.write
-/// [`flush()`]: #tymethod.flush
+/// [`write`]: #tymethod.write
+/// [`flush`]: #tymethod.flush
 /// [`std::io`]: index.html
 ///
 /// # Examples
@@ -872,6 +890,9 @@ pub trait Write {
     /// It is **not** considered an error if the entire buffer could not be
     /// written to this writer.
     ///
+    /// An error of the `ErrorKind::Interrupted` kind is non-fatal and the
+    /// write operation should be retried if there is nothing else to do.
+    ///
     /// # Examples
     ///
     /// ```
@@ -881,6 +902,7 @@ pub trait Write {
     /// # fn foo() -> std::io::Result<()> {
     /// let mut buffer = File::create("foo.txt")?;
     ///
+    /// // Writes some prefix of the byte string, not necessarily all of it.
     /// buffer.write(b"some bytes")?;
     /// # Ok(())
     /// # }
@@ -916,14 +938,17 @@ pub trait Write {
 
     /// Attempts to write an entire buffer into this write.
     ///
-    /// This method will continuously call `write` while there is more data to
-    /// write. This method will not return until the entire buffer has been
-    /// successfully written or an error occurs. The first error generated from
-    /// this method will be returned.
+    /// This method will continuously call `write` until there is no more data
+    /// to be written or an error of non-`ErrorKind::Interrupted` kind is
+    /// returned. This method will not return until the entire buffer has been
+    /// successfully written or such an error occurs. The first error that is
+    /// not of `ErrorKind::Interrupted` kind generated from this method will be
+    /// returned.
     ///
     /// # Errors
     ///
-    /// This function will return the first error that `write` returns.
+    /// This function will return the first error of
+    /// non-`ErrorKind::Interrupted` kind that `write` returns.
     ///
     /// # Examples
     ///
@@ -1159,7 +1184,7 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// For example, reading line-by-line is inefficient without using a buffer, so
 /// if you want to read by line, you'll need `BufRead`, which includes a
-/// [`read_line()`] method as well as a [`lines()`] iterator.
+/// [`read_line`] method as well as a [`lines`] iterator.
 ///
 /// # Examples
 ///
@@ -1183,8 +1208,8 @@ fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
 ///
 /// [`BufReader`]: struct.BufReader.html
 /// [`File`]: ../fs/struct.File.html
-/// [`read_line()`]: #method.read_line
-/// [`lines()`]: #method.lines
+/// [`read_line`]: #method.read_line
+/// [`lines`]: #method.lines
 /// [`Read`]: trait.Read.html
 ///
 /// ```
@@ -1209,13 +1234,13 @@ pub trait BufRead: Read {
     /// Fills the internal buffer of this object, returning the buffer contents.
     ///
     /// This function is a lower-level call. It needs to be paired with the
-    /// [`consume()`] method to function properly. When calling this
+    /// [`consume`] method to function properly. When calling this
     /// method, none of the contents will be "read" in the sense that later
-    /// calling `read` may return the same contents. As such, [`consume()`] must
+    /// calling `read` may return the same contents. As such, [`consume`] must
     /// be called with the number of bytes that are consumed from this buffer to
     /// ensure that the bytes are never returned twice.
     ///
-    /// [`consume()`]: #tymethod.consume
+    /// [`consume`]: #tymethod.consume
     ///
     /// An empty buffer returned indicates that the stream has reached EOF.
     ///
@@ -1256,21 +1281,21 @@ pub trait BufRead: Read {
     /// so they should no longer be returned in calls to `read`.
     ///
     /// This function is a lower-level call. It needs to be paired with the
-    /// [`fill_buf()`] method to function properly. This function does
+    /// [`fill_buf`] method to function properly. This function does
     /// not perform any I/O, it simply informs this object that some amount of
-    /// its buffer, returned from [`fill_buf()`], has been consumed and should
+    /// its buffer, returned from [`fill_buf`], has been consumed and should
     /// no longer be returned. As such, this function may do odd things if
-    /// [`fill_buf()`] isn't called before calling it.
+    /// [`fill_buf`] isn't called before calling it.
     ///
     /// The `amt` must be `<=` the number of bytes in the buffer returned by
-    /// [`fill_buf()`].
+    /// [`fill_buf`].
     ///
     /// # Examples
     ///
-    /// Since `consume()` is meant to be used with [`fill_buf()`],
+    /// Since `consume()` is meant to be used with [`fill_buf`],
     /// that method's example includes an example of `consume()`.
     ///
-    /// [`fill_buf()`]: #tymethod.fill_buf
+    /// [`fill_buf`]: #tymethod.fill_buf
     #[stable(feature = "rust1", since = "1.0.0")]
     fn consume(&mut self, amt: usize);
 
@@ -1285,33 +1310,47 @@ pub trait BufRead: Read {
     /// # Errors
     ///
     /// This function will ignore all instances of [`ErrorKind::Interrupted`] and
-    /// will otherwise return any errors returned by [`fill_buf()`].
+    /// will otherwise return any errors returned by [`fill_buf`].
     ///
     /// If an I/O error is encountered then all bytes read so far will be
     /// present in `buf` and its length will have been adjusted appropriately.
     ///
-    /// # Examples
-    ///
-    /// A locked standard input implements `BufRead`. In this example, we'll
-    /// read from standard input until we see an `a` byte.
-    ///
-    /// [`fill_buf()`]: #tymethod.fill_buf
+    /// [`fill_buf`]: #tymethod.fill_buf
     /// [`ErrorKind::Interrupted`]: enum.ErrorKind.html#variant.Interrupted
     ///
-    /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
+    /// # Examples
     ///
-    /// fn foo() -> io::Result<()> {
-    /// let stdin = io::stdin();
-    /// let mut stdin = stdin.lock();
-    /// let mut buffer = Vec::new();
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to read all the bytes in a byte slice
+    /// in hyphen delimited segments:
     ///
-    /// stdin.read_until(b'a', &mut buffer)?;
+    /// [`Cursor`]: struct.Cursor.html
     ///
-    /// println!("{:?}", buffer);
-    /// # Ok(())
-    /// # }
+    /// ```
+    /// use std::io::{self, BufRead};
+    ///
+    /// let mut cursor = io::Cursor::new(b"lorem-ipsum");
+    /// let mut buf = vec![];
+    ///
+    /// // cursor is at 'l'
+    /// let num_bytes = cursor.read_until(b'-', &mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 6);
+    /// assert_eq!(buf, b"lorem-");
+    /// buf.clear();
+    ///
+    /// // cursor is at 'i'
+    /// let num_bytes = cursor.read_until(b'-', &mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 5);
+    /// assert_eq!(buf, b"ipsum");
+    /// buf.clear();
+    ///
+    /// // cursor is at EOF
+    /// let num_bytes = cursor.read_until(b'-', &mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 0);
+    /// assert_eq!(buf, b"");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
@@ -1330,35 +1369,43 @@ pub trait BufRead: Read {
     ///
     /// # Errors
     ///
-    /// This function has the same error semantics as [`read_until()`] and will
+    /// This function has the same error semantics as [`read_until`] and will
     /// also return an error if the read bytes are not valid UTF-8. If an I/O
     /// error is encountered then `buf` may contain some bytes already read in
     /// the event that all data read so far was valid UTF-8.
     ///
     /// # Examples
     ///
-    /// A locked standard input implements `BufRead`. In this example, we'll
-    /// read all of the lines from standard input. If we were to do this in
-    /// an actual project, the [`lines()`] method would be easier, of
-    /// course.
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to read all the lines in a byte slice:
     ///
-    /// [`lines()`]: #method.lines
-    /// [`read_until()`]: #method.read_until
+    /// [`Cursor`]: struct.Cursor.html
     ///
     /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
-    ///
-    /// let stdin = io::stdin();
-    /// let mut stdin = stdin.lock();
-    /// let mut buffer = String::new();
-    ///
-    /// while stdin.read_line(&mut buffer).unwrap() > 0 {
-    ///     // work with buffer
-    ///     println!("{:?}", buffer);
-    ///
-    ///     buffer.clear();
-    /// }
+    /// use std::io::{self, BufRead};
+    ///
+    /// let mut cursor = io::Cursor::new(b"foo\nbar");
+    /// let mut buf = String::new();
+    ///
+    /// // cursor is at 'f'
+    /// let num_bytes = cursor.read_line(&mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 4);
+    /// assert_eq!(buf, "foo\n");
+    /// buf.clear();
+    ///
+    /// // cursor is at 'b'
+    /// let num_bytes = cursor.read_line(&mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 3);
+    /// assert_eq!(buf, "bar");
+    /// buf.clear();
+    ///
+    /// // cursor is at EOF
+    /// let num_bytes = cursor.read_line(&mut buf)
+    ///     .expect("reading from cursor won't fail");
+    /// assert_eq!(num_bytes, 0);
+    /// assert_eq!(buf, "");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn read_line(&mut self, buf: &mut String) -> Result<usize> {
@@ -1375,27 +1422,31 @@ pub trait BufRead: Read {
     /// [`io::Result`]`<`[`Vec<u8>`]`>`. Each vector returned will *not* have
     /// the delimiter byte at the end.
     ///
-    /// This function will yield errors whenever [`read_until()`] would have
+    /// This function will yield errors whenever [`read_until`] would have
     /// also yielded an error.
     ///
+    /// [`io::Result`]: type.Result.html
+    /// [`Vec<u8>`]: ../vec/struct.Vec.html
+    /// [`read_until`]: #method.read_until
+    ///
     /// # Examples
     ///
-    /// A locked standard input implements `BufRead`. In this example, we'll
-    /// read some input from standard input, splitting on commas.
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to iterate over all hyphen delimited
+    /// segments in a byte slice
     ///
-    /// [`io::Result`]: type.Result.html
-    /// [`Vec<u8>`]: ../vec/struct.Vec.html
-    /// [`read_until()`]: #method.read_until
+    /// [`Cursor`]: struct.Cursor.html
     ///
     /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
+    /// use std::io::{self, BufRead};
     ///
-    /// let stdin = io::stdin();
+    /// let cursor = io::Cursor::new(b"lorem-ipsum-dolor");
     ///
-    /// for content in stdin.lock().split(b',') {
-    ///     println!("{:?}", content.unwrap());
-    /// }
+    /// let mut split_iter = cursor.split(b'-').map(|l| l.unwrap());
+    /// assert_eq!(split_iter.next(), Some(b"lorem".to_vec()));
+    /// assert_eq!(split_iter.next(), Some(b"ipsum".to_vec()));
+    /// assert_eq!(split_iter.next(), Some(b"dolor".to_vec()));
+    /// assert_eq!(split_iter.next(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn split(self, byte: u8) -> Split<Self> where Self: Sized {
@@ -1413,24 +1464,29 @@ pub trait BufRead: Read {
     ///
     /// # Examples
     ///
-    /// A locked standard input implements `BufRead`:
+    /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
+    /// this example, we use [`Cursor`] to iterate over all the lines in a byte
+    /// slice.
+    ///
+    /// [`Cursor`]: struct.Cursor.html
     ///
     /// ```
-    /// use std::io;
-    /// use std::io::prelude::*;
+    /// use std::io::{self, BufRead};
     ///
-    /// let stdin = io::stdin();
+    /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor");
     ///
-    /// for line in stdin.lock().lines() {
-    ///     println!("{}", line.unwrap());
-    /// }
+    /// let mut lines_iter = cursor.lines().map(|l| l.unwrap());
+    /// assert_eq!(lines_iter.next(), Some(String::from("lorem")));
+    /// assert_eq!(lines_iter.next(), Some(String::from("ipsum")));
+    /// assert_eq!(lines_iter.next(), Some(String::from("dolor")));
+    /// assert_eq!(lines_iter.next(), None);
     /// ```
     ///
     /// # Errors
     ///
-    /// Each line of the iterator has the same error semantics as [`BufRead::read_line()`].
+    /// Each line of the iterator has the same error semantics as [`BufRead::read_line`].
     ///
-    /// [`BufRead::read_line()`]: trait.BufRead.html#method.read_line
+    /// [`BufRead::read_line`]: trait.BufRead.html#method.read_line
     #[stable(feature = "rust1", since = "1.0.0")]
     fn lines(self) -> Lines<Self> where Self: Sized {
         Lines { buf: self }
@@ -1439,10 +1495,10 @@ pub trait BufRead: Read {
 
 /// Adaptor to chain together two readers.
 ///
-/// This struct is generally created by calling [`chain()`] on a reader.
-/// Please see the documentation of [`chain()`] for more details.
+/// This struct is generally created by calling [`chain`] on a reader.
+/// Please see the documentation of [`chain`] for more details.
 ///
-/// [`chain()`]: trait.Read.html#method.chain
+/// [`chain`]: trait.Read.html#method.chain
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chain<T, U> {
     first: T,
@@ -1450,6 +1506,87 @@ pub struct Chain<T, U> {
     done_first: bool,
 }
 
+impl<T, U> Chain<T, U> {
+    /// Consumes the `Chain`, returning the wrapped readers.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(more_io_inner_methods)]
+    ///
+    /// # use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let mut foo_file = File::open("foo.txt")?;
+    /// let mut bar_file = File::open("bar.txt")?;
+    ///
+    /// let chain = foo_file.chain(bar_file);
+    /// let (foo_file, bar_file) = chain.into_inner();
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "more_io_inner_methods", issue="41519")]
+    pub fn into_inner(self) -> (T, U) {
+        (self.first, self.second)
+    }
+
+    /// Gets references to the underlying readers in this `Chain`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(more_io_inner_methods)]
+    ///
+    /// # use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let mut foo_file = File::open("foo.txt")?;
+    /// let mut bar_file = File::open("bar.txt")?;
+    ///
+    /// let chain = foo_file.chain(bar_file);
+    /// let (foo_file, bar_file) = chain.get_ref();
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "more_io_inner_methods", issue="41519")]
+    pub fn get_ref(&self) -> (&T, &U) {
+        (&self.first, &self.second)
+    }
+
+    /// Gets mutable references to the underlying readers in this `Chain`.
+    ///
+    /// Care should be taken to avoid modifying the internal I/O state of the
+    /// underlying readers as doing so may corrupt the internal state of this
+    /// `Chain`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(more_io_inner_methods)]
+    ///
+    /// # use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let mut foo_file = File::open("foo.txt")?;
+    /// let mut bar_file = File::open("bar.txt")?;
+    ///
+    /// let mut chain = foo_file.chain(bar_file);
+    /// let (foo_file, bar_file) = chain.get_mut();
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "more_io_inner_methods", issue="41519")]
+    pub fn get_mut(&mut self) -> (&mut T, &mut U) {
+        (&mut self.first, &mut self.second)
+    }
+}
+
 #[stable(feature = "std_debug", since = "1.16.0")]
 impl<T: fmt::Debug, U: fmt::Debug> fmt::Debug for Chain<T, U> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -1496,10 +1633,10 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
 
 /// Reader adaptor which limits the bytes read from an underlying reader.
 ///
-/// This struct is generally created by calling [`take()`] on a reader.
-/// Please see the documentation of [`take()`] for more details.
+/// This struct is generally created by calling [`take`] on a reader.
+/// Please see the documentation of [`take`] for more details.
 ///
-/// [`take()`]: trait.Read.html#method.take
+/// [`take`]: trait.Read.html#method.take
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Take<T> {
@@ -1562,6 +1699,64 @@ impl<T> Take<T> {
     pub fn into_inner(self) -> T {
         self.inner
     }
+
+    /// Gets a reference to the underlying reader.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(more_io_inner_methods)]
+    ///
+    /// use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let mut file = File::open("foo.txt")?;
+    ///
+    /// let mut buffer = [0; 5];
+    /// let mut handle = file.take(5);
+    /// handle.read(&mut buffer)?;
+    ///
+    /// let file = handle.get_ref();
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "more_io_inner_methods", issue="41519")]
+    pub fn get_ref(&self) -> &T {
+        &self.inner
+    }
+
+    /// Gets a mutable reference to the underlying reader.
+    ///
+    /// Care should be taken to avoid modifying the internal I/O state of the
+    /// underlying reader as doing so may corrupt the internal limit of this
+    /// `Take`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(more_io_inner_methods)]
+    ///
+    /// use std::io;
+    /// use std::io::prelude::*;
+    /// use std::fs::File;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let mut file = File::open("foo.txt")?;
+    ///
+    /// let mut buffer = [0; 5];
+    /// let mut handle = file.take(5);
+    /// handle.read(&mut buffer)?;
+    ///
+    /// let file = handle.get_mut();
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[unstable(feature = "more_io_inner_methods", issue="41519")]
+    pub fn get_mut(&mut self) -> &mut T {
+        &mut self.inner
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1614,10 +1809,10 @@ fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
 
 /// An iterator over `u8` values of a reader.
 ///
-/// This struct is generally created by calling [`bytes()`] on a reader.
-/// Please see the documentation of [`bytes()`] for more details.
+/// This struct is generally created by calling [`bytes`] on a reader.
+/// Please see the documentation of [`bytes`] for more details.
 ///
-/// [`bytes()`]: trait.Read.html#method.bytes
+/// [`bytes`]: trait.Read.html#method.bytes
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Bytes<R> {
@@ -1635,7 +1830,7 @@ impl<R: Read> Iterator for Bytes<R> {
 
 /// An iterator over the `char`s of a reader.
 ///
-/// This struct is generally created by calling [`chars()`][chars] on a reader.
+/// This struct is generally created by calling [`chars`][chars] on a reader.
 /// Please see the documentation of `chars()` for more details.
 ///
 /// [chars]: trait.Read.html#method.chars
@@ -1726,7 +1921,7 @@ impl fmt::Display for CharsError {
 /// An iterator over the contents of an instance of `BufRead` split on a
 /// particular byte.
 ///
-/// This struct is generally created by calling [`split()`][split] on a
+/// This struct is generally created by calling [`split`][split] on a
 /// `BufRead`. Please see the documentation of `split()` for more details.
 ///
 /// [split]: trait.BufRead.html#method.split
@@ -1758,7 +1953,7 @@ impl<B: BufRead> Iterator for Split<B> {
 
 /// An iterator over the lines of an instance of `BufRead`.
 ///
-/// This struct is generally created by calling [`lines()`][lines] on a
+/// This struct is generally created by calling [`lines`][lines] on a
 /// `BufRead`. Please see the documentation of `lines()` for more details.
 ///
 /// [lines]: trait.BufRead.html#method.lines
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index e16e8019b5f..a8b0bf0071a 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -17,7 +17,7 @@ use io::{self, BufReader, LineWriter};
 use sync::{Arc, Mutex, MutexGuard};
 use sys::stdio;
 use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
-use thread::LocalKeyState;
+use thread::{LocalKey, LocalKeyState};
 
 /// Stdout used by print! and println! macros
 thread_local! {
@@ -332,11 +332,11 @@ impl<'a> fmt::Debug for StdinLock<'a> {
 ///
 /// Each handle shares a global buffer of data to be written to the standard
 /// output stream. Access is also synchronized via a lock and explicit control
-/// over locking is available via the [`lock()`] method.
+/// over locking is available via the [`lock`] method.
 ///
 /// Created by the [`io::stdout`] method.
 ///
-/// [`lock()`]: #method.lock
+/// [`lock`]: #method.lock
 /// [`io::stdout`]: fn.stdout.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
@@ -659,41 +659,56 @@ pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
     })
 }
 
-#[unstable(feature = "print",
-           reason = "implementation detail which may disappear or be replaced at any time",
-           issue = "0")]
-#[doc(hidden)]
-pub fn _print(args: fmt::Arguments) {
-    // As an implementation of the `println!` macro, we want to try our best to
-    // not panic wherever possible and get the output somewhere. There are
-    // currently two possible vectors for panics we take care of here:
-    //
-    // 1. If the TLS key for the local stdout has been destroyed, accessing it
-    //    would cause a panic. Note that we just lump in the uninitialized case
-    //    here for convenience, we're not trying to avoid a panic.
-    // 2. If the local stdout is currently in use (e.g. we're in the middle of
-    //    already printing) then accessing again would cause a panic.
-    //
-    // If, however, the actual I/O causes an error, we do indeed panic.
-    let result = match LOCAL_STDOUT.state() {
+/// Write `args` to output stream `local_s` if possible, `global_s`
+/// otherwise. `label` identifies the stream in a panic message.
+///
+/// This function is used to print error messages, so it takes extra
+/// care to avoid causing a panic when `local_stream` is unusable.
+/// For instance, if the TLS key for the local stream is uninitialized
+/// or already destroyed, or if the local stream is locked by another
+/// thread, it will just fall back to the global stream.
+///
+/// However, if the actual I/O causes an error, this function does panic.
+fn print_to<T>(args: fmt::Arguments,
+               local_s: &'static LocalKey<RefCell<Option<Box<Write+Send>>>>,
+               global_s: fn() -> T,
+               label: &str) where T: Write {
+    let result = match local_s.state() {
         LocalKeyState::Uninitialized |
-        LocalKeyState::Destroyed => stdout().write_fmt(args),
+        LocalKeyState::Destroyed => global_s().write_fmt(args),
         LocalKeyState::Valid => {
-            LOCAL_STDOUT.with(|s| {
+            local_s.with(|s| {
                 if let Ok(mut borrowed) = s.try_borrow_mut() {
                     if let Some(w) = borrowed.as_mut() {
                         return w.write_fmt(args);
                     }
                 }
-                stdout().write_fmt(args)
+                global_s().write_fmt(args)
             })
         }
     };
     if let Err(e) = result {
-        panic!("failed printing to stdout: {}", e);
+        panic!("failed printing to {}: {}", label, e);
     }
 }
 
+#[unstable(feature = "print_internals",
+           reason = "implementation detail which may disappear or be replaced at any time",
+           issue = "0")]
+#[doc(hidden)]
+pub fn _print(args: fmt::Arguments) {
+    print_to(args, &LOCAL_STDOUT, stdout, "stdout");
+}
+
+#[unstable(feature = "print_internals",
+           reason = "implementation detail which may disappear or be replaced at any time",
+           issue = "0")]
+#[doc(hidden)]
+pub fn _eprint(args: fmt::Arguments) {
+    use panicking::LOCAL_STDERR;
+    print_to(args, &LOCAL_STDERR, stderr, "stderr");
+}
+
 #[cfg(test)]
 mod tests {
     use thread;
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 4163187488e..078f1ad3f6c 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -63,7 +63,7 @@ pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<
 
 /// A reader which is always at EOF.
 ///
-/// This struct is generally created by calling [`empty()`][empty]. Please see
+/// This struct is generally created by calling [`empty`][empty]. Please see
 /// the documentation of `empty()` for more details.
 ///
 /// [empty]: fn.empty.html
@@ -107,7 +107,7 @@ impl fmt::Debug for Empty {
 
 /// A reader which yields one byte over and over and over and over and over and...
 ///
-/// This struct is generally created by calling [`repeat()`][repeat]. Please
+/// This struct is generally created by calling [`repeat`][repeat]. Please
 /// see the documentation of `repeat()` for more details.
 ///
 /// [repeat]: fn.repeat.html
@@ -150,7 +150,7 @@ impl fmt::Debug for Repeat {
 
 /// A writer which will move data into the void.
 ///
-/// This struct is generally created by calling [`sink()`][sink]. Please
+/// This struct is generally created by calling [`sink`][sink]. Please
 /// see the documentation of `sink()` for more details.
 ///
 /// [sink]: fn.sink.html
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 070690773b6..b0820d6f05a 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -21,7 +21,7 @@
 //! contained an `extern crate std;` import at the [crate root]. Therefore the
 //! standard library can be accessed in [`use`] statements through the path
 //! `std`, as in [`use std::env`], or in expressions through the absolute path
-//! `::std`, as in [`::std::env::args()`].
+//! `::std`, as in [`::std::env::args`].
 //!
 //! # How to read this documentation
 //!
@@ -94,6 +94,17 @@
 //! compiler - but they are documented here the same). Like the prelude, the
 //! standard macros are imported by default into all crates.
 //!
+//! # Contributing changes to the documentation
+//!
+//! Check out the rust contribution guidelines [here](
+//! https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md).
+//! The source for this documentation can be found on [Github](https://github.com/rust-lang).
+//! To contribute changes, make sure you read the guidelines first, then submit
+//! pull-requests for your suggested changes.
+//!
+//! Contributions are appreciated! If you see a part of the docs that can be
+//! improved, submit a PR, or chat with us first on irc.mozilla.org #rust-docs.
+//!
 //! # A Tour of The Rust Standard Library
 //!
 //! The rest of this crate documentation is dedicated to pointing out notable
@@ -156,7 +167,7 @@
 //! [TCP]: net/struct.TcpStream.html
 //! [The Rust Prelude]: prelude/index.html
 //! [UDP]: net/struct.UdpSocket.html
-//! [`::std::env::args()`]: env/fn.args.html
+//! [`::std::env::args`]: env/fn.args.html
 //! [`Arc`]: sync/struct.Arc.html
 //! [owned slice]: boxed/index.html
 //! [`Cell`]: cell/struct.Cell.html
@@ -174,7 +185,7 @@
 //! [slice]: primitive.slice.html
 //! [`atomic`]: sync/atomic/index.html
 //! [`collections`]: collections/index.html
-//! [`for`]: ../book/loops.html#for
+//! [`for`]: ../book/first-edition/loops.html#for
 //! [`format!`]: macro.format.html
 //! [`fs`]: fs/index.html
 //! [`io`]: io/index.html
@@ -189,14 +200,14 @@
 //! [`sync`]: sync/index.html
 //! [`thread`]: thread/index.html
 //! [`use std::env`]: env/index.html
-//! [`use`]: ../book/crates-and-modules.html#importing-modules-with-use
-//! [crate root]: ../book/crates-and-modules.html#basic-terminology-crates-and-modules
+//! [`use`]: ../book/first-edition/crates-and-modules.html#importing-modules-with-use
+//! [crate root]: ../book/first-edition/crates-and-modules.html#basic-terminology-crates-and-modules
 //! [crates.io]: https://crates.io
-//! [deref coercions]: ../book/deref-coercions.html
+//! [deref coercions]: ../book/first-edition/deref-coercions.html
 //! [files]: fs/struct.File.html
 //! [multithreading]: thread/index.html
 //! [other]: #what-is-in-the-standard-library-documentation
-//! [primitive types]: ../book/primitive-types.html
+//! [primitive types]: ../book/first-edition/primitive-types.html
 
 #![crate_name = "std"]
 #![stable(feature = "rust1", since = "1.0.0")]
@@ -237,7 +248,6 @@
 #![feature(allow_internal_unstable)]
 #![feature(asm)]
 #![feature(associated_consts)]
-#![feature(borrow_state)]
 #![feature(box_syntax)]
 #![feature(cfg_target_has_atomic)]
 #![feature(cfg_target_thread_local)]
@@ -245,7 +255,6 @@
 #![feature(char_escape_debug)]
 #![feature(char_internals)]
 #![feature(collections)]
-#![feature(collections_bound)]
 #![feature(collections_range)]
 #![feature(compiler_builtins_lib)]
 #![feature(const_fn)]
@@ -253,7 +262,6 @@
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
-#![feature(float_extras)]
 #![feature(float_from_str_radix)]
 #![feature(fn_traits)]
 #![feature(fnbox)]
@@ -273,6 +281,8 @@
 #![feature(linkage)]
 #![feature(macro_reexport)]
 #![feature(needs_panic_runtime)]
+#![feature(needs_drop)]
+#![feature(never_type)]
 #![feature(num_bits_bytes)]
 #![feature(old_wrapping)]
 #![feature(on_unimplemented)]
@@ -281,8 +291,8 @@
 #![feature(panic_unwind)]
 #![feature(peek)]
 #![feature(placement_in_syntax)]
+#![feature(placement_new_protocol)]
 #![feature(prelude_import)]
-#![feature(pub_restricted)]
 #![feature(rand)]
 #![feature(raw)]
 #![feature(repr_simd)]
@@ -296,9 +306,11 @@
 #![feature(stmt_expr_attributes)]
 #![feature(str_char)]
 #![feature(str_internals)]
+#![feature(str_mut_extras)]
 #![feature(str_utf16)]
 #![feature(test, rustc_private)]
 #![feature(thread_local)]
+#![feature(toowned_clone_into)]
 #![feature(try_from)]
 #![feature(unboxed_closures)]
 #![feature(unicode)]
@@ -306,8 +318,8 @@
 #![feature(untagged_unions)]
 #![feature(unwind_attributes)]
 #![feature(vec_push_all)]
-#![feature(zero_one)]
 #![cfg_attr(test, feature(update_panic_count))]
+#![cfg_attr(test, feature(float_bits_conv))]
 
 // Explicitly import the prelude. The compiler uses this same unstable attribute
 // to import the prelude implicitly when building crates that depend on std.
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index a1f092621cb..df3fce0da76 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -68,6 +68,9 @@ macro_rules! panic {
 /// necessary to use `io::stdout().flush()` to ensure the output is emitted
 /// immediately.
 ///
+/// Use `print!` only for the primary output of your program.  Use
+/// `eprint!` instead to print error and progress messages.
+///
 /// # Panics
 ///
 /// Panics if writing to `io::stdout()` fails.
@@ -105,9 +108,12 @@ macro_rules! print {
 /// Use the `format!` syntax to write data to the standard output.
 /// See `std::fmt` for more information.
 ///
+/// Use `println!` only for the primary output of your program.  Use
+/// `eprintln!` instead to print error and progress messages.
+///
 /// # Panics
 ///
-/// Panics if writing to `io::stdout()` fails.
+/// Panics if writing to `io::stdout` fails.
 ///
 /// # Examples
 ///
@@ -124,6 +130,45 @@ macro_rules! println {
     ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
 }
 
+/// Macro for printing to the standard error.
+///
+/// Equivalent to the `print!` macro, except that output goes to
+/// `io::stderr` instead of `io::stdout`.  See `print!` for
+/// example usage.
+///
+/// Use `eprint!` only for error and progress messages.  Use `print!`
+/// instead for the primary output of your program.
+///
+/// # Panics
+///
+/// Panics if writing to `io::stderr` fails.
+#[macro_export]
+#[stable(feature = "eprint", since = "1.19.0")]
+#[allow_internal_unstable]
+macro_rules! eprint {
+    ($($arg:tt)*) => ($crate::io::_eprint(format_args!($($arg)*)));
+}
+
+/// Macro for printing to the standard error, with a newline.
+///
+/// Equivalent to the `println!` macro, except that output goes to
+/// `io::stderr` instead of `io::stdout`.  See `println!` for
+/// example usage.
+///
+/// Use `eprintln!` only for error and progress messages.  Use `println!`
+/// instead for the primary output of your program.
+///
+/// # Panics
+///
+/// Panics if writing to `io::stderr` fails.
+#[macro_export]
+#[stable(feature = "eprint", since = "1.19.0")]
+macro_rules! eprintln {
+    () => (eprint!("\n"));
+    ($fmt:expr) => (eprint!(concat!($fmt, "\n")));
+    ($fmt:expr, $($arg:tt)*) => (eprint!(concat!($fmt, "\n"), $($arg)*));
+}
+
 /// A macro to select an event from a number of receivers.
 ///
 /// This macro is used to wait for the first event to occur on a number of
diff --git a/src/libstd/net/addr.rs b/src/libstd/net/addr.rs
index 84c4acb8d92..36c06dc0b58 100644
--- a/src/libstd/net/addr.rs
+++ b/src/libstd/net/addr.rs
@@ -20,15 +20,31 @@ use vec;
 use iter;
 use slice;
 
-/// Representation of a socket address for networking applications.
+/// An internet socket address, either IPv4 or IPv6.
 ///
-/// A socket address can either represent the IPv4 or IPv6 protocol and is
-/// paired with at least a port number as well. Each protocol may have more
-/// specific information about the address available to it as well.
+/// Internet socket addresses consist of an [IP address], a 16-bit port number, as well
+/// as possibly some version-dependent additional information. See [`SocketAddrV4`]'s and
+/// [`SocketAddrV6`]'s respective documentation for more details.
+///
+/// [IP address]: ../../std/net/enum.IpAddr.html
+/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::{IpAddr, Ipv4Addr, SocketAddr};
+///
+/// let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
+///
+/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
+/// assert_eq!(socket.port(), 8080);
+/// assert_eq!(socket.is_ipv4(), true);
+/// ```
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum SocketAddr {
-    /// An IPv4 socket address which is a (ip, port) combination.
+    /// An IPv4 socket address.
     #[stable(feature = "rust1", since = "1.0.0")]
     V4(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV4),
     /// An IPv6 socket address.
@@ -36,18 +52,63 @@ pub enum SocketAddr {
     V6(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV6),
 }
 
-/// An IPv4 socket address which is a (ip, port) combination.
+/// An IPv4 socket address.
+///
+/// IPv4 socket addresses consist of an [IPv4 address] and a 16-bit port number, as
+/// stated in [IETF RFC 793].
+///
+/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
+///
+/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
+/// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::{Ipv4Addr, SocketAddrV4};
+///
+/// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
+///
+/// assert_eq!("127.0.0.1:8080".parse(), Ok(socket));
+/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
+/// assert_eq!(socket.port(), 8080);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SocketAddrV4 { inner: c::sockaddr_in }
 
 /// An IPv6 socket address.
+///
+/// IPv6 socket addresses consist of an [Ipv6 address], a 16-bit port number, as well
+/// as fields containing the traffic class, the flow label, and a scope identifier
+/// (see [IETF RFC 2553, Section 3.3] for more details).
+///
+/// See [`SocketAddr`] for a type encompassing both IPv4 and IPv6 socket addresses.
+///
+/// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
+/// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::{Ipv6Addr, SocketAddrV6};
+///
+/// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
+///
+/// assert_eq!("[2001:db8::1]:8080".parse(), Ok(socket));
+/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
+/// assert_eq!(socket.port(), 8080);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SocketAddrV6 { inner: c::sockaddr_in6 }
 
 impl SocketAddr {
-    /// Creates a new socket address from the (ip, port) pair.
+    /// Creates a new socket address from an [IP address] and a port number.
+    ///
+    /// [IP address]: ../../std/net/enum.IpAddr.html
     ///
     /// # Examples
     ///
@@ -84,7 +145,7 @@ impl SocketAddr {
         }
     }
 
-    /// Change the IP address associated with this socket address.
+    /// Changes the IP address associated with this socket address.
     ///
     /// # Examples
     ///
@@ -123,7 +184,7 @@ impl SocketAddr {
         }
     }
 
-    /// Change the port number associated with this socket address.
+    /// Changes the port number associated with this socket address.
     ///
     /// # Examples
     ///
@@ -142,8 +203,13 @@ impl SocketAddr {
         }
     }
 
-    /// Returns true if the IP in this `SocketAddr` is a valid IPv4 address,
-    /// false if it's a valid IPv6 address.
+    /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
+    /// [IPv4 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IP address]: ../../std/net/enum.IpAddr.html
+    /// [IPv4 address]: ../../std/net/enum.IpAddr.html#variant.V4
     ///
     /// # Examples
     ///
@@ -164,8 +230,13 @@ impl SocketAddr {
         }
     }
 
-    /// Returns true if the IP in this `SocketAddr` is a valid IPv6 address,
-    /// false if it's a valid IPv4 address.
+    /// Returns [`true`] if the [IP address] in this `SocketAddr` is an
+    /// [IPv6 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IP address]: ../../std/net/enum.IpAddr.html
+    /// [IPv6 address]: ../../std/net/enum.IpAddr.html#variant.V6
     ///
     /// # Examples
     ///
@@ -189,7 +260,9 @@ impl SocketAddr {
 }
 
 impl SocketAddrV4 {
-    /// Creates a new socket address from the (ip, port) pair.
+    /// Creates a new socket address from an [IPv4 address] and a port number.
+    ///
+    /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
     ///
     /// # Examples
     ///
@@ -227,7 +300,7 @@ impl SocketAddrV4 {
         }
     }
 
-    /// Change the IP address associated with this socket address.
+    /// Changes the IP address associated with this socket address.
     ///
     /// # Examples
     ///
@@ -258,7 +331,7 @@ impl SocketAddrV4 {
         ntoh(self.inner.sin_port)
     }
 
-    /// Change the port number associated with this socket address.
+    /// Changes the port number associated with this socket address.
     ///
     /// # Examples
     ///
@@ -276,8 +349,14 @@ impl SocketAddrV4 {
 }
 
 impl SocketAddrV6 {
-    /// Creates a new socket address from the ip/port/flowinfo/scope_id
-    /// components.
+    /// Creates a new socket address from an [IPv6 address], a 16-bit port number,
+    /// and the `flowinfo` and `scope_id` fields.
+    ///
+    /// For more information on the meaning and layout of the `flowinfo` and `scope_id`
+    /// parameters, see [IETF RFC 2553, Section 3.3].
+    ///
+    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
+    /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
     ///
     /// # Examples
     ///
@@ -318,7 +397,7 @@ impl SocketAddrV6 {
         }
     }
 
-    /// Change the IP address associated with this socket address.
+    /// Changes the IP address associated with this socket address.
     ///
     /// # Examples
     ///
@@ -349,7 +428,7 @@ impl SocketAddrV6 {
         ntoh(self.inner.sin6_port)
     }
 
-    /// Change the port number associated with this socket address.
+    /// Changes the port number associated with this socket address.
     ///
     /// # Examples
     ///
@@ -365,8 +444,17 @@ impl SocketAddrV6 {
         self.inner.sin6_port = hton(new_port);
     }
 
-    /// Returns the flow information associated with this address,
-    /// corresponding to the `sin6_flowinfo` field in C.
+    /// Returns the flow information associated with this address.
+    ///
+    /// This information corresponds to the `sin6_flowinfo` field in C's `netinet/in.h`,
+    /// as specified in [IETF RFC 2553, Section 3.3].
+    /// It combines information about the flow label and the traffic class as specified
+    /// in [IETF RFC 2460], respectively [Section 6] and [Section 7].
+    ///
+    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
+    /// [IETF RFC 2460]: https://tools.ietf.org/html/rfc2460
+    /// [Section 6]: https://tools.ietf.org/html/rfc2460#section-6
+    /// [Section 7]: https://tools.ietf.org/html/rfc2460#section-7
     ///
     /// # Examples
     ///
@@ -381,7 +469,11 @@ impl SocketAddrV6 {
         self.inner.sin6_flowinfo
     }
 
-    /// Change the flow information associated with this socket address.
+    /// Changes the flow information associated with this socket address.
+    ///
+    /// See the [`flowinfo`] method's documentation for more details.
+    ///
+    /// [`flowinfo`]: #method.flowinfo
     ///
     /// # Examples
     ///
@@ -397,8 +489,12 @@ impl SocketAddrV6 {
         self.inner.sin6_flowinfo = new_flowinfo;
     }
 
-    /// Returns the scope ID associated with this address,
-    /// corresponding to the `sin6_scope_id` field in C.
+    /// Returns the scope ID associated with this address.
+    ///
+    /// This information corresponds to the `sin6_scope_id` field in C's `netinet/in.h`,
+    /// as specified in [IETF RFC 2553, Section 3.3].
+    ///
+    /// [IETF RFC 2553, Section 3.3]: https://tools.ietf.org/html/rfc2553#section-3.3
     ///
     /// # Examples
     ///
@@ -415,6 +511,10 @@ impl SocketAddrV6 {
 
     /// Change the scope ID associated with this socket address.
     ///
+    /// See the [`scope_id`] method's documentation for more details.
+    ///
+    /// [`scope_id`]: #method.scope_id
+    ///
     /// # Examples
     ///
     /// ```
@@ -559,37 +659,51 @@ impl hash::Hash for SocketAddrV6 {
 }
 
 /// A trait for objects which can be converted or resolved to one or more
-/// `SocketAddr` values.
+/// [`SocketAddr`] values.
 ///
 /// This trait is used for generic address resolution when constructing network
 /// objects.  By default it is implemented for the following types:
 ///
-///  * `SocketAddr`, `SocketAddrV4`, `SocketAddrV6` - `to_socket_addrs` is
-///    identity function.
+///  * [`SocketAddr`]: [`to_socket_addrs`] is the identity function.
 ///
-///  * `(IpvNAddr, u16)` - `to_socket_addrs` constructs `SocketAddr` trivially.
+///  * [`SocketAddrV4`], [`SocketAddrV6`], `(`[`IpAddr`]`, `[`u16`]`)`,
+///    `(`[`Ipv4Addr`]`, `[`u16`]`)`, `(`[`Ipv6Addr`]`, `[`u16`]`)`:
+///    [`to_socket_addrs`] constructs a [`SocketAddr`] trivially.
 ///
-///  * `(&str, u16)` - the string should be either a string representation of an
-///    IP address expected by `FromStr` implementation for `IpvNAddr` or a host
+///  * `(`[`&str`]`, `[`u16`]`)`: the string should be either a string representation
+///    of an [`IpAddr`] address as expected by [`FromStr`] implementation or a host
 ///    name.
 ///
-///  * `&str` - the string should be either a string representation of a
-///    `SocketAddr` as expected by its `FromStr` implementation or a string like
-///    `<host_name>:<port>` pair where `<port>` is a `u16` value.
+///  * [`&str`]: the string should be either a string representation of a
+///    [`SocketAddr`] as expected by its [`FromStr`] implementation or a string like
+///    `<host_name>:<port>` pair where `<port>` is a [`u16`] value.
 ///
-/// This trait allows constructing network objects like `TcpStream` or
-/// `UdpSocket` easily with values of various types for the bind/connection
+/// This trait allows constructing network objects like [`TcpStream`] or
+/// [`UdpSocket`] easily with values of various types for the bind/connection
 /// address. It is needed because sometimes one type is more appropriate than
 /// the other: for simple uses a string like `"localhost:12345"` is much nicer
-/// than manual construction of the corresponding `SocketAddr`, but sometimes
-/// `SocketAddr` value is *the* main source of the address, and converting it to
+/// than manual construction of the corresponding [`SocketAddr`], but sometimes
+/// [`SocketAddr`] value is *the* main source of the address, and converting it to
 /// some other type (e.g. a string) just for it to be converted back to
-/// `SocketAddr` in constructor methods is pointless.
+/// [`SocketAddr`] in constructor methods is pointless.
 ///
 /// Addresses returned by the operating system that are not IP addresses are
 /// silently ignored.
 ///
-/// Some examples:
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+/// [`&str`]: ../../std/primitive.str.html
+/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+/// [`to_socket_addrs`]: #tymethod.to_socket_addrs
+/// [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
+/// [`u16`]: ../../std/primitive.u16.html
+///
+/// # Examples
 ///
 /// ```no_run
 /// use std::net::{SocketAddrV4, TcpStream, UdpSocket, TcpListener, Ipv4Addr};
@@ -629,10 +743,6 @@ pub trait ToSocketAddrs {
     ///
     /// Note that this function may block the current thread while resolution is
     /// performed.
-    ///
-    /// # Errors
-    ///
-    /// Any errors encountered during resolution will be returned as an `Err`.
     #[stable(feature = "rust1", since = "1.0.0")]
     fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
 }
diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs
index 5d6e8d319d7..1e5368896af 100644
--- a/src/libstd/net/ip.rs
+++ b/src/libstd/net/ip.rs
@@ -21,44 +21,100 @@ use net::{hton, ntoh};
 use sys::net::netc as c;
 use sys_common::{AsInner, FromInner};
 
-/// An IP address, either an IPv4 or IPv6 address.
+/// An IP address, either IPv4 or IPv6.
 ///
-/// # Examples
+/// This enum can contain either an [`Ipv4Addr`] or an [`Ipv6Addr`], see their
+/// respective documentation for more details.
 ///
-/// Constructing an IPv4 address:
+/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
 ///
-/// ```
-/// use std::net::{IpAddr, Ipv4Addr};
+/// # Examples
 ///
-/// IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
 /// ```
+/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 ///
-/// Constructing an IPv6 address:
+/// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
+/// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
 ///
-/// ```
-/// use std::net::{IpAddr, Ipv6Addr};
+/// assert_eq!("127.0.0.1".parse(), Ok(localhost_v4));
+/// assert_eq!("::1".parse(), Ok(localhost_v6));
 ///
-/// IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+/// assert_eq!(localhost_v4.is_ipv6(), false);
+/// assert_eq!(localhost_v4.is_ipv4(), true);
 /// ```
 #[stable(feature = "ip_addr", since = "1.7.0")]
 #[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
 pub enum IpAddr {
-    /// Representation of an IPv4 address.
+    /// An IPv4 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
     V4(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv4Addr),
-    /// Representation of an IPv6 address.
+    /// An IPv6 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
     V6(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv6Addr),
 }
 
-/// Representation of an IPv4 address.
+/// An IPv4 address.
+///
+/// IPv4 addresses are defined as 32-bit integers in [IETF RFC 791].
+/// They are usually represented as four octets.
+///
+/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
+///
+/// [IETF RFC 791]: https://tools.ietf.org/html/rfc791
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+///
+/// # Textual representation
+///
+/// `Ipv4Addr` provides a [`FromStr`] implementation. The four octets are in decimal
+/// notation, divided by `.` (this is called "dot-decimal notation").
+///
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+///
+/// # Examples
+///
+/// ```
+/// use std::net::Ipv4Addr;
+///
+/// let localhost = Ipv4Addr::new(127, 0, 0, 1);
+/// assert_eq!("127.0.0.1".parse(), Ok(localhost));
+/// assert_eq!(localhost.is_loopback(), true);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv4Addr {
     inner: c::in_addr,
 }
 
-/// Representation of an IPv6 address.
+/// An IPv6 address.
+///
+/// IPv6 addresses are defined as 128-bit integers in [IETF RFC 4291].
+/// They are usually represented as eight 16-bit segments.
+///
+/// See [`IpAddr`] for a type encompassing both IPv4 and IPv6 addresses.
+///
+/// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+///
+/// # Textual representation
+///
+/// `Ipv6Addr` provides a [`FromStr`] implementation. There are many ways to represent
+/// an IPv6 address in text, but in general, each segments is written in hexadecimal
+/// notation, and segments are separated by `:`. For more information, see
+/// [IETF RFC 5952].
+///
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+/// [IETF RFC 5952]: https://tools.ietf.org/html/rfc5952
+///
+/// # Examples
+///
+/// ```
+/// use std::net::Ipv6Addr;
+///
+/// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
+/// assert_eq!("::1".parse(), Ok(localhost));
+/// assert_eq!(localhost.is_loopback(), true);
+/// ```
 #[derive(Copy)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Ipv6Addr {
@@ -78,10 +134,14 @@ pub enum Ipv6MulticastScope {
 }
 
 impl IpAddr {
-    /// Returns true for the special 'unspecified' address ([IPv4], [IPv6]).
+    /// Returns [`true`] for the special 'unspecified' address.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_unspecified`][IPv4] and
+    /// [`Ipv6Addr::is_unspecified`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_unspecified
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_unspecified
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -99,10 +159,14 @@ impl IpAddr {
         }
     }
 
-    /// Returns true if this is a loopback address ([IPv4], [IPv6]).
+    /// Returns [`true`] if this is a loopback address.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_loopback`][IPv4] and
+    /// [`Ipv6Addr::is_loopback`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_loopback
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_loopback
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -120,10 +184,14 @@ impl IpAddr {
         }
     }
 
-    /// Returns true if the address appears to be globally routable ([IPv4], [IPv6]).
+    /// Returns [`true`] if the address appears to be globally routable.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_global`][IPv4] and
+    /// [`Ipv6Addr::is_global`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_global
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_global
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -145,10 +213,14 @@ impl IpAddr {
         }
     }
 
-    /// Returns true if this is a multicast address ([IPv4], [IPv6]).
+    /// Returns [`true`] if this is a multicast address.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_multicast`][IPv4] and
+    /// [`Ipv6Addr::is_multicast`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_multicast
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_multicast
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -166,10 +238,14 @@ impl IpAddr {
         }
     }
 
-    /// Returns true if this address is in a range designated for documentation ([IPv4], [IPv6]).
+    /// Returns [`true`] if this address is in a range designated for documentation.
+    ///
+    /// See the documentation for [`Ipv4Addr::is_documentation`][IPv4] and
+    /// [`Ipv6Addr::is_documentation`][IPv6] for more details.
     ///
     /// [IPv4]: ../../std/net/struct.Ipv4Addr.html#method.is_documentation
     /// [IPv6]: ../../std/net/struct.Ipv6Addr.html#method.is_documentation
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -191,7 +267,11 @@ impl IpAddr {
         }
     }
 
-    /// Returns true if this address is a valid IPv4 address, false if it's a valid IPv6 address.
+    /// Returns [`true`] if this address is an [IPv4 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IPv4 address]: #variant.V4
     ///
     /// # Examples
     ///
@@ -212,7 +292,11 @@ impl IpAddr {
         }
     }
 
-    /// Returns true if this address is a valid IPv6 address, false if it's a valid IPv4 address.
+    /// Returns [`true`] if this address is an [IPv6 address], and [`false`] otherwise.
+    ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    /// [IPv6 address]: #variant.V6
     ///
     /// # Examples
     ///
@@ -274,12 +358,13 @@ 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
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -294,11 +379,12 @@ impl Ipv4Addr {
         self.inner.s_addr == 0
     }
 
-    /// Returns true if this is a loopback address (127.0.0.0/8).
+    /// Returns [`true`] if this is a loopback address (127.0.0.0/8).
     ///
-    /// This property is defined by [RFC 1122].
+    /// This property is defined by [IETF RFC 1122].
     ///
-    /// [RFC 1122]: https://tools.ietf.org/html/rfc1122
+    /// [IETF RFC 1122]: https://tools.ietf.org/html/rfc1122
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -313,15 +399,16 @@ impl Ipv4Addr {
         self.octets()[0] == 127
     }
 
-    /// Returns true if this is a private address.
+    /// Returns [`true`] if this is a private address.
     ///
-    /// The private address ranges are defined in [RFC 1918] and include:
+    /// The private address ranges are defined in [IETF RFC 1918] and include:
     ///
     ///  - 10.0.0.0/8
     ///  - 172.16.0.0/12
     ///  - 192.168.0.0/16
     ///
-    /// [RFC 1918]: https://tools.ietf.org/html/rfc1918
+    /// [IETF RFC 1918]: https://tools.ietf.org/html/rfc1918
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -346,11 +433,12 @@ impl Ipv4Addr {
         }
     }
 
-    /// Returns true if the address is link-local (169.254.0.0/16).
+    /// Returns [`true`] if the address is link-local (169.254.0.0/16).
     ///
-    /// This property is defined by [RFC 3927].
+    /// This property is defined by [IETF RFC 3927].
     ///
-    /// [RFC 3927]: https://tools.ietf.org/html/rfc3927
+    /// [IETF RFC 3927]: https://tools.ietf.org/html/rfc3927
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -366,7 +454,7 @@ impl Ipv4Addr {
         self.octets()[0] == 169 && self.octets()[1] == 254
     }
 
-    /// Returns true if the address appears to be globally routable.
+    /// Returns [`true`] if the address appears to be globally routable.
     /// See [iana-ipv4-special-registry][ipv4-sr].
     ///
     /// The following return false:
@@ -379,6 +467,7 @@ impl Ipv4Addr {
     /// - the unspecified address (0.0.0.0)
     ///
     /// [ipv4-sr]: http://goo.gl/RaZ7lg
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -400,12 +489,13 @@ impl Ipv4Addr {
         !self.is_broadcast() && !self.is_documentation() && !self.is_unspecified()
     }
 
-    /// Returns true if this is a multicast address (224.0.0.0/4).
+    /// 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 [IETF RFC 5771].
     ///
-    /// [RFC 5771]: https://tools.ietf.org/html/rfc5771
+    /// [IETF RFC 5771]: https://tools.ietf.org/html/rfc5771
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -421,11 +511,12 @@ impl Ipv4Addr {
         self.octets()[0] >= 224 && self.octets()[0] <= 239
     }
 
-    /// Returns true if this is a broadcast address (255.255.255.255).
+    /// 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 [IETF RFC 919].
     ///
-    /// [RFC 919]: https://tools.ietf.org/html/rfc919
+    /// [IETF RFC 919]: https://tools.ietf.org/html/rfc919
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -441,15 +532,16 @@ impl Ipv4Addr {
         self.octets()[2] == 255 && self.octets()[3] == 255
     }
 
-    /// Returns true if this address is in a range designated for documentation.
+    /// Returns [`true`] if this address is in a range designated for documentation.
     ///
-    /// This is defined in [RFC 5737]:
+    /// This is defined in [IETF RFC 5737]:
     ///
     /// - 192.0.2.0/24 (TEST-NET-1)
     /// - 198.51.100.0/24 (TEST-NET-2)
     /// - 203.0.113.0/24 (TEST-NET-3)
     ///
-    /// [RFC 5737]: https://tools.ietf.org/html/rfc5737
+    /// [IETF RFC 5737]: https://tools.ietf.org/html/rfc5737
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -471,10 +563,12 @@ impl Ipv4Addr {
         }
     }
 
-    /// Converts this address to an IPv4-compatible IPv6 address.
+    /// Converts this address to an IPv4-compatible [IPv6 address].
     ///
     /// a.b.c.d becomes ::a.b.c.d
     ///
+    /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -490,10 +584,12 @@ impl Ipv4Addr {
                       ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16)
     }
 
-    /// Converts this address to an IPv4-mapped IPv6 address.
+    /// Converts this address to an IPv4-mapped [IPv6 address].
     ///
     /// a.b.c.d becomes ::ffff:a.b.c.d
     ///
+    /// [IPv6 address]: ../../std/net/struct.Ipv6Addr.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -561,7 +657,7 @@ impl PartialEq for Ipv4Addr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<Ipv4Addr> for IpAddr {
     fn eq(&self, other: &Ipv4Addr) -> bool {
         match *self {
@@ -571,7 +667,7 @@ impl PartialEq<Ipv4Addr> for IpAddr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<IpAddr> for Ipv4Addr {
     fn eq(&self, other: &IpAddr) -> bool {
         match *other {
@@ -598,7 +694,7 @@ impl PartialOrd for Ipv4Addr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<Ipv4Addr> for IpAddr {
     fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
         match *self {
@@ -608,7 +704,7 @@ impl PartialOrd<Ipv4Addr> for IpAddr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<IpAddr> for Ipv4Addr {
     fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
         match *other {
@@ -636,6 +732,7 @@ impl FromInner<c::in_addr> for Ipv4Addr {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<Ipv4Addr> for u32 {
+    /// It performs the conversion in network order (big-endian).
     fn from(ip: Ipv4Addr) -> u32 {
         let ip = ip.octets();
         ((ip[0] as u32) << 24) + ((ip[1] as u32) << 16) + ((ip[2] as u32) << 8) + (ip[3] as u32)
@@ -644,6 +741,7 @@ impl From<Ipv4Addr> for u32 {
 
 #[stable(feature = "ip_u32", since = "1.1.0")]
 impl From<u32> for Ipv4Addr {
+    /// It performs the conversion in network order (big-endian).
     fn from(ip: u32) -> Ipv4Addr {
         Ipv4Addr::new((ip >> 24) as u8, (ip >> 16) as u8, (ip >> 8) as u8, ip as u8)
     }
@@ -715,11 +813,12 @@ impl Ipv6Addr {
         ]
     }
 
-    /// Returns true for the special 'unspecified' address (::).
+    /// Returns [`true`] for the special 'unspecified' address (::).
     ///
-    /// This property is defined in [RFC 4291].
+    /// This property is defined in [IETF RFC 4291].
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -734,11 +833,12 @@ impl Ipv6Addr {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 0]
     }
 
-    /// Returns true if this is a loopback address (::1).
+    /// Returns [`true`] if this is a loopback address (::1).
     ///
-    /// This property is defined in [RFC 4291].
+    /// This property is defined in [IETF RFC 4291].
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -753,14 +853,17 @@ impl Ipv6Addr {
         self.segments() == [0, 0, 0, 0, 0, 0, 0, 1]
     }
 
-    /// Returns true if the address appears to be globally routable.
+    /// Returns [`true`] if the address appears to be globally routable.
     ///
-    /// The following return false:
+    /// The following return [`false`]:
     ///
     /// - the loopback address
     /// - link-local, site-local, and unique local unicast addresses
     /// - interface-, link-, realm-, admin- and site-local multicast addresses
     ///
+    /// [`true`]: ../../std/primitive.bool.html
+    /// [`false`]: ../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -782,11 +885,12 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns true if this is a unique local address (fc00::/7).
+    /// Returns [`true`] if this is a unique local address (fc00::/7).
     ///
-    /// This property is defined in [RFC 4193].
+    /// This property is defined in [IETF RFC 4193].
     ///
-    /// [RFC 4193]: https://tools.ietf.org/html/rfc4193
+    /// [IETF RFC 4193]: https://tools.ietf.org/html/rfc4193
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -805,11 +909,12 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xfe00) == 0xfc00
     }
 
-    /// Returns true if the address is unicast and link-local (fe80::/10).
+    /// Returns [`true`] if the address is unicast and link-local (fe80::/10).
     ///
-    /// This property is defined in [RFC 4291].
+    /// This property is defined in [IETF RFC 4291].
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -828,9 +933,11 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xffc0) == 0xfe80
     }
 
-    /// Returns true if this is a deprecated unicast site-local address
+    /// Returns [`true`] if this is a deprecated unicast site-local address
     /// (fec0::/10).
     ///
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -848,12 +955,13 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xffc0) == 0xfec0
     }
 
-    /// Returns true if this is an address reserved for documentation
+    /// Returns [`true`] if this is an address reserved for documentation
     /// (2001:db8::/32).
     ///
-    /// This property is defined in [RFC 3849].
+    /// This property is defined in [IETF RFC 3849].
     ///
-    /// [RFC 3849]: https://tools.ietf.org/html/rfc3849
+    /// [IETF RFC 3849]: https://tools.ietf.org/html/rfc3849
+    /// [`true`]: ../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -872,7 +980,7 @@ impl Ipv6Addr {
         (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
     }
 
-    /// Returns true if the address is a globally routable unicast address.
+    /// Returns [`true`] if the address is a globally routable unicast address.
     ///
     /// The following return false:
     ///
@@ -883,6 +991,8 @@ impl Ipv6Addr {
     /// - the unspecified address
     /// - the address range reserved for documentation
     ///
+    /// [`true`]: ../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -935,11 +1045,13 @@ impl Ipv6Addr {
         }
     }
 
-    /// Returns true if this is a multicast address (ff00::/8).
+    /// Returns [`true`] if this is a multicast address (ff00::/8).
+    ///
+    /// This property is defined by [IETF RFC 4291].
     ///
-    /// This property is defined by [RFC 4291].
+    /// [IETF RFC 4291]: https://tools.ietf.org/html/rfc4291
+    /// [`true`]: ../../std/primitive.bool.html
     ///
-    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
     /// # Examples
     ///
     /// ```
@@ -953,11 +1065,16 @@ impl Ipv6Addr {
         (self.segments()[0] & 0xff00) == 0xff00
     }
 
-    /// Converts this address to an IPv4 address. Returns None if this address is
+    /// Converts this address to an [IPv4 address]. Returns [`None`] if this address is
     /// neither IPv4-compatible or IPv4-mapped.
     ///
     /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d
     ///
+    /// [IPv4 address]: ../../std/net/struct.Ipv4Addr.html
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    ///
+    /// # Examples
+    ///
     /// ```
     /// use std::net::{Ipv4Addr, Ipv6Addr};
     ///
@@ -1083,7 +1200,7 @@ impl PartialEq for Ipv6Addr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<IpAddr> for Ipv6Addr {
     fn eq(&self, other: &IpAddr) -> bool {
         match *other {
@@ -1093,7 +1210,7 @@ impl PartialEq<IpAddr> for Ipv6Addr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialEq<Ipv6Addr> for IpAddr {
     fn eq(&self, other: &Ipv6Addr) -> bool {
         match *self {
@@ -1120,7 +1237,7 @@ impl PartialOrd for Ipv6Addr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<Ipv6Addr> for IpAddr {
     fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
         match *self {
@@ -1130,7 +1247,7 @@ impl PartialOrd<Ipv6Addr> for IpAddr {
     }
 }
 
-#[stable(feature = "ip_cmp", since = "1.15.0")]
+#[stable(feature = "ip_cmp", since = "1.16.0")]
 impl PartialOrd<IpAddr> for Ipv6Addr {
     fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
         match *other {
@@ -1185,7 +1302,7 @@ impl From<[u8; 16]> for Ipv6Addr {
     }
 }
 
-#[stable(feature = "ipv6_from_segments", since = "1.15.0")]
+#[stable(feature = "ipv6_from_segments", since = "1.16.0")]
 impl From<[u16; 8]> for Ipv6Addr {
     fn from(segments: [u16; 8]) -> Ipv6Addr {
         let [a, b, c, d, e, f, g, h] = segments;
diff --git a/src/libstd/net/mod.rs b/src/libstd/net/mod.rs
index b0d2e3e4687..9fcb93e2032 100644
--- a/src/libstd/net/mod.rs
+++ b/src/libstd/net/mod.rs
@@ -9,6 +9,32 @@
 // except according to those terms.
 
 //! Networking primitives for TCP/UDP communication.
+//!
+//! This module provides networking functionality for the Transmission Control and User
+//! Datagram Protocols, as well as types for IP and socket addresses.
+//!
+//! # Organization
+//!
+//! * [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
+//! * [`UdpSocket`] provides functionality for communication over UDP
+//! * [`IpAddr`] represents IP addresses of either IPv4 or IPv6; [`Ipv4Addr`] and
+//!   [`Ipv6Addr`] are respectively IPv4 and IPv6 addresses
+//! * [`SocketAddr`] represents socket addresses of either IPv4 or IPv6; [`SocketAddrV4`]
+//!   and [`SocketAddrV6`] are respectively IPv4 and IPv6 socket addresses
+//! * [`ToSocketAddrs`] is a trait that used for generic address resolution when interacting
+//!   with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`]
+//! * Other types are return or parameter types for various methods in this module
+//!
+//! [`IpAddr`]: ../../std/net/enum.IpAddr.html
+//! [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+//! [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
+//! [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+//! [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+//! [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
+//! [`TcpListener`]: ../../std/net/struct.TcpListener.html
+//! [`TcpStream`]: ../../std/net/struct.TcpStream.html
+//! [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
+//! [`UdpSocket`]: ../../std/net/struct.UdpSocket.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -43,17 +69,30 @@ mod test;
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Shutdown {
-    /// Indicates that the reading portion of this stream/socket should be shut
-    /// down. All currently blocked and future reads will return `Ok(0)`.
+    /// The reading portion of the [`TcpStream`] should be shut down.
+    ///
+    /// All currently blocked and future [reads] will return [`Ok(0)`].
+    ///
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    /// [reads]: ../../std/io/trait.Read.html
+    /// [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok
     #[stable(feature = "rust1", since = "1.0.0")]
     Read,
-    /// Indicates that the writing portion of this stream/socket should be shut
-    /// down. All currently blocked and future writes will return an error.
+    /// The writing portion of the [`TcpStream`] should be shut down.
+    ///
+    /// All currently blocked and future [writes] will return an error.
+    ///
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    /// [writes]: ../../std/io/trait.Write.html
     #[stable(feature = "rust1", since = "1.0.0")]
     Write,
-    /// Shut down both the reading and writing portions of this stream.
+    /// Both the reading and the writing portions of the [`TcpStream`] should be shut down.
+    ///
+    /// See [`Shutdown::Read`] and [`Shutdown::Write`] for more information.
     ///
-    /// See `Shutdown::Read` and `Shutdown::Write` for more information.
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    /// [`Shutdown::Read`]: #variant.Read
+    /// [`Shutdown::Write`]: #variant.Write
     #[stable(feature = "rust1", since = "1.0.0")]
     Both,
 }
diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs
index d86711c10ac..7d7c67ff3f9 100644
--- a/src/libstd/net/parser.rs
+++ b/src/libstd/net/parser.rs
@@ -368,7 +368,19 @@ impl FromStr for SocketAddr {
     }
 }
 
-/// An error returned when parsing an IP address or a socket address.
+/// An error which can be returned when parsing an IP address or a socket address.
+///
+/// This error is used as the error type for the [`FromStr`] implementation for
+/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
+/// [`SocketAddrV6`].
+///
+/// [`FromStr`]: ../../std/str/trait.FromStr.html
+/// [`IpAddr`]: ../../std/net/enum.IpAddr.html
+/// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
+/// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
+/// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+/// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
+/// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct AddrParseError(());
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 9bead22ef7f..c1493c9c6f4 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -17,10 +17,25 @@ use sys_common::net as net_imp;
 use sys_common::{AsInner, FromInner, IntoInner};
 use time::Duration;
 
-/// A structure which represents a TCP stream between a local socket and a
-/// remote socket.
+/// A TCP stream between a local and a remote socket.
 ///
-/// The socket will be closed when the value is dropped.
+/// After creating a `TcpStream` by either [`connect`]ing to a remote host or
+/// [`accept`]ing a connection on a [`TcpListener`], data can be transmitted
+/// by [reading] and [writing] to it.
+///
+/// The connection will be closed when the value is dropped. The reading and writing
+/// portions of the connection can also be shut down individually with the [`shutdown`]
+/// method.
+///
+/// The Transmission Control Protocol is specified in [IETF RFC 793].
+///
+/// [`accept`]: ../../std/net/struct.TcpListener.html#method.accept
+/// [`connect`]: #method.connect
+/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
+/// [reading]: ../../std/io/trait.Read.html
+/// [`shutdown`]: #method.shutdown
+/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
+/// [writing]: ../../std/io/trait.Write.html
 ///
 /// # Examples
 ///
@@ -39,42 +54,53 @@ use time::Duration;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpStream(net_imp::TcpStream);
 
-/// A structure representing a socket server.
+/// A TCP socket server, listening for connections.
+///
+/// After creating a `TcpListener` by [`bind`]ing it to a socket address, it listens
+/// for incoming TCP connections. These can be accepted by calling [`accept`] or by
+/// iterating over the [`Incoming`] iterator returned by [`incoming`][`TcpListener::incoming`].
+///
+/// The socket will be closed when the value is dropped.
+///
+/// The Transmission Control Protocol is specified in [IETF RFC 793].
+///
+/// [`accept`]: #method.accept
+/// [`bind`]: #method.bind
+/// [IETF RFC 793]: https://tools.ietf.org/html/rfc793
+/// [`Incoming`]: ../../std/net/struct.Incoming.html
+/// [`TcpListener::incoming`]: #method.incoming
 ///
 /// # Examples
 ///
-/// ```no_run
+/// ```
+/// # use std::io;
 /// use std::net::{TcpListener, TcpStream};
 ///
-/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
-///
 /// fn handle_client(stream: TcpStream) {
 ///     // ...
 /// }
 ///
+/// # fn process() -> io::Result<()> {
+/// let listener = TcpListener::bind("127.0.0.1:80").unwrap();
+///
 /// // accept connections and process them serially
 /// for stream in listener.incoming() {
-///     match stream {
-///         Ok(stream) => {
-///             handle_client(stream);
-///         }
-///         Err(e) => { /* connection failed */ }
-///     }
+///     handle_client(stream?);
 /// }
+/// # Ok(())
+/// # }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct TcpListener(net_imp::TcpListener);
 
-/// An infinite iterator over the connections from a `TcpListener`.
-///
-/// This iterator will infinitely yield [`Some`] of the accepted connections. It
-/// is equivalent to calling `accept` in a loop.
+/// An iterator that infinitely [`accept`]s connections on a [`TcpListener`].
 ///
 /// This `struct` is created by the [`incoming`] method on [`TcpListener`].
+/// See its documentation for more.
 ///
-/// [`Some`]: ../../std/option/enum.Option.html#variant.Some
-/// [`incoming`]: struct.TcpListener.html#method.incoming
-/// [`TcpListener`]: struct.TcpListener.html
+/// [`accept`]: ../../std/net/struct.TcpListener.html#method.accept
+/// [`incoming`]: ../../std/net/struct.TcpListener.html#method.incoming
+/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Incoming<'a> { listener: &'a TcpListener }
@@ -83,11 +109,15 @@ impl TcpStream {
     /// Opens a TCP connection to a remote host.
     ///
     /// `addr` is an address of the remote host. Anything which implements
-    /// `ToSocketAddrs` trait can be supplied for the address; see this trait
+    /// [`ToSocketAddrs`] trait can be supplied for the address; see this trait
     /// documentation for concrete examples.
-    /// In case `ToSocketAddrs::to_socket_addrs()` returns more than one entry,
+    /// In case [`ToSocketAddrs::to_socket_addrs()`] returns more than one entry,
     /// then the first valid and reachable address is used.
     ///
+    /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
+    /// [`ToSocketAddrs::to_socket_addrs()`]:
+    /// ../../std/net/trait.ToSocketAddrs.html#tymethod.to_socket_addrs
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -146,6 +176,13 @@ impl TcpStream {
     ///
     /// [`Shutdown`]: ../../std/net/enum.Shutdown.html
     ///
+    /// # Platform-specific behavior
+    ///
+    /// Calling this function multiple times may result in different behavior,
+    /// depending on the operating system. On Linux, the second call will
+    /// return `Ok(())`, but on macOS, it will return `ErrorKind::NotConnected`.
+    /// This may change in the future.
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -183,7 +220,7 @@ impl TcpStream {
 
     /// Sets the read timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`read()`] calls will block
+    /// If the value specified is [`None`], then [`read`] calls will block
     /// indefinitely. It is an error to pass the zero `Duration` to this
     /// method.
     ///
@@ -194,7 +231,7 @@ impl TcpStream {
     /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
     ///
@@ -214,7 +251,7 @@ impl TcpStream {
 
     /// Sets the write timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`write()`] calls will block
+    /// If the value specified is [`None`], then [`write`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
@@ -225,7 +262,7 @@ impl TcpStream {
     /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
@@ -246,14 +283,14 @@ impl TcpStream {
 
     /// Returns the read timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`read()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
     ///
     /// # Note
     ///
     /// Some platforms do not provide access to the current timeout.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     ///
     /// # Examples
     ///
@@ -272,14 +309,14 @@ impl TcpStream {
 
     /// Returns the write timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`write()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
     ///
     /// # Note
     ///
     /// Some platforms do not provide access to the current timeout.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     ///
     /// # Examples
     ///
@@ -306,7 +343,6 @@ impl TcpStream {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(peek)]
     /// use std::net::TcpStream;
     ///
     /// let stream = TcpStream::connect("127.0.0.1:8000")
@@ -314,7 +350,7 @@ impl TcpStream {
     /// let mut buf = [0; 10];
     /// let len = stream.peek(&mut buf).expect("peek failed");
     /// ```
-    #[unstable(feature = "peek", issue = "38980")]
+    #[stable(feature = "peek", since = "1.18.0")]
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.peek(buf)
     }
@@ -494,11 +530,14 @@ impl TcpListener {
     ///
     /// Binding with a port number of 0 will request that the OS assigns a port
     /// to this listener. The port allocated can be queried via the
-    /// `local_addr` method.
+    /// [`local_addr`] method.
     ///
-    /// The address type can be any implementor of `ToSocketAddrs` trait. See
+    /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
     /// its documentation for concrete examples.
     ///
+    /// [`local_addr`]: #method.local_addr
+    /// [`ToSocketAddrs`]: ../../std/net/trait.ToSocketAddrs.html
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -529,10 +568,12 @@ impl TcpListener {
 
     /// Creates a new independently owned handle to the underlying socket.
     ///
-    /// The returned `TcpListener` is a reference to the same socket that this
+    /// The returned [`TcpListener`] 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.
     ///
+    /// [`TcpListener`]: ../../std/net/struct.TcpListener.html
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -549,9 +590,11 @@ impl TcpListener {
     /// Accept a new incoming connection from this listener.
     ///
     /// This function will block the calling thread until a new TCP connection
-    /// is established. When established, the corresponding `TcpStream` and the
+    /// is established. When established, the corresponding [`TcpStream`] and the
     /// remote peer's address will be returned.
     ///
+    /// [`TcpStream`]: ../../std/net/struct.TcpStream.html
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -572,10 +615,12 @@ impl TcpListener {
     /// listener.
     ///
     /// The returned iterator will never return [`None`] and will also not yield
-    /// the peer's [`SocketAddr`] structure.
+    /// the peer's [`SocketAddr`] structure. Iterating over it is equivalent to
+    /// calling [`accept`] in a loop.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
+    /// [`accept`]: #method.accept
     ///
     /// # Examples
     ///
@@ -618,7 +663,7 @@ impl TcpListener {
 
     /// Gets the value of the `IP_TTL` option for this socket.
     ///
-    /// For more information about this option, see [`set_ttl()`][link].
+    /// For more information about this option, see [`set_ttl`][link].
     ///
     /// [link]: #method.set_ttl
     ///
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index f452c75d389..80151dc2b44 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -15,11 +15,29 @@ use sys_common::net as net_imp;
 use sys_common::{AsInner, FromInner, IntoInner};
 use time::Duration;
 
-/// A User Datagram Protocol socket.
+/// A UDP socket.
 ///
-/// This is an implementation of a bound UDP socket. This supports both IPv4 and
-/// IPv6 addresses, and there is no corresponding notion of a server because UDP
-/// is a datagram protocol.
+/// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
+/// [sent to] and [received from] any other socket address.
+///
+/// Although UDP is a connectionless protocol, this implementation provides an interface
+/// to set an address where data should be sent and received from. After setting a remote
+/// address with [`connect`], data can be sent to and received from that address with
+/// [`send`] and [`recv`].
+///
+/// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is
+/// an unordered, unreliable protocol; refer to [`TcpListener`] and [`TcpStream`] for TCP
+/// primitives.
+///
+/// [`bind`]: #method.bind
+/// [`connect`]: #method.connect
+/// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
+/// [`recv`]: #method.recv
+/// [received from]: #method.recv_from
+/// [`send`]: #method.send
+/// [sent to]: #method.send_to
+/// [`TcpListener`]: ../../std/net/struct.TcpListener.html
+/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
 ///
 /// # Examples
 ///
@@ -94,7 +112,6 @@ impl UdpSocket {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(peek)]
     /// use std::net::UdpSocket;
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
@@ -102,7 +119,7 @@ impl UdpSocket {
     /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
     ///                                         .expect("Didn't receive data");
     /// ```
-    #[unstable(feature = "peek", issue = "38980")]
+    #[stable(feature = "peek", since = "1.18.0")]
     pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
         self.0.peek_from(buf)
     }
@@ -175,7 +192,7 @@ impl UdpSocket {
 
     /// Sets the read timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`read()`] calls will block
+    /// If the value specified is [`None`], then [`read`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
@@ -186,7 +203,7 @@ impl UdpSocket {
     /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
@@ -206,7 +223,7 @@ impl UdpSocket {
 
     /// Sets the write timeout to the timeout specified.
     ///
-    /// If the value specified is [`None`], then [`write()`] calls will block
+    /// If the value specified is [`None`], then [`write`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
@@ -217,7 +234,7 @@ impl UdpSocket {
     /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     /// [`Duration`]: ../../std/time/struct.Duration.html
     /// [`WouldBlock`]: ../../std/io/enum.ErrorKind.html#variant.WouldBlock
     /// [`TimedOut`]: ../../std/io/enum.ErrorKind.html#variant.TimedOut
@@ -237,10 +254,10 @@ impl UdpSocket {
 
     /// Returns the read timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`read()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../std/io/trait.Read.html#tymethod.read
     ///
     /// # Examples
     ///
@@ -258,10 +275,10 @@ impl UdpSocket {
 
     /// Returns the write timeout of this socket.
     ///
-    /// If the timeout is [`None`], then [`write()`] calls will block indefinitely.
+    /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
-    /// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
+    /// [`write`]: ../../std/io/trait.Write.html#tymethod.write
     ///
     /// # Examples
     ///
@@ -560,10 +577,10 @@ impl UdpSocket {
 
     /// Sends data on the socket to the remote address to which it is connected.
     ///
-    /// The [`connect()`] method will connect this socket to a remote address. This
+    /// The [`connect`] method will connect this socket to a remote address. This
     /// method will fail if the socket is not connected.
     ///
-    /// [`connect()`]: #method.connect
+    /// [`connect`]: #method.connect
     ///
     /// # Examples
     ///
@@ -582,9 +599,11 @@ impl UdpSocket {
     /// Receives data on the socket from the remote address to which it is
     /// connected.
     ///
-    /// The `connect` method will connect this socket to a remote address. This
+    /// The [`connect`] method will connect this socket to a remote address. This
     /// method will fail if the socket is not connected.
     ///
+    /// [`connect`]: #method.connect
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -618,7 +637,6 @@ impl UdpSocket {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(peek)]
     /// use std::net::UdpSocket;
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
@@ -629,7 +647,7 @@ impl UdpSocket {
     ///     Err(e) => println!("peek function failed: {:?}", e),
     /// }
     /// ```
-    #[unstable(feature = "peek", issue = "38980")]
+    #[stable(feature = "peek", since = "1.18.0")]
     pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
         self.0.peek(buf)
     }
diff --git a/src/libstd/num.rs b/src/libstd/num.rs
index 5f83d077a13..ff89887ac92 100644
--- a/src/libstd/num.rs
+++ b/src/libstd/num.rs
@@ -17,9 +17,6 @@
 #![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, TryFromIntError};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::num::Wrapping;
diff --git a/src/libstd/os/android/raw.rs b/src/libstd/os/android/raw.rs
index 5e473a933a6..60ad8fcc54c 100644
--- a/src/libstd/os/android/raw.rs
+++ b/src/libstd/os/android/raw.rs
@@ -165,3 +165,66 @@ mod arch {
     }
 }
 
+#[cfg(target_arch = "x86_64")]
+mod arch {
+    use os::raw::{c_uint, c_long, c_ulong};
+    use os::unix::raw::{uid_t, gid_t};
+
+    #[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;
+
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type blkcnt_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type blksize_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type ino_t = u64;
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub type nlink_t = u32;
+    #[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;
+
+    #[repr(C)]
+    #[derive(Clone)]
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub struct stat {
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_dev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ino: ino_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_nlink: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mode: c_uint,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_uid: uid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_gid: gid_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_rdev: dev_t,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_size: i64,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blksize: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_blocks: c_long,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_atime_nsec: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_mtime_nsec: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime: c_ulong,
+        #[stable(feature = "raw_ext", since = "1.1.0")]
+        pub st_ctime_nsec: c_ulong,
+        __unused: [c_long; 3],
+    }
+}
+
diff --git a/src/libstd/os/linux/fs.rs b/src/libstd/os/linux/fs.rs
index 11c41816cec..7ebda5ed744 100644
--- a/src/libstd/os/linux/fs.rs
+++ b/src/libstd/os/linux/fs.rs
@@ -34,36 +34,55 @@ pub trait MetadataExt {
     #[allow(deprecated)]
     fn as_raw_stat(&self) -> &raw::stat;
 
+    /// Returns the device ID on which this file resides.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_dev(&self) -> u64;
+    /// Returns the inode number.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ino(&self) -> u64;
+    /// Returns the file type and mode.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mode(&self) -> u32;
+    /// Returns the number of hard links to file.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_nlink(&self) -> u64;
+    /// Returns the user ID of the file owner.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_uid(&self) -> u32;
+    /// Returns the group ID of the file owner.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_gid(&self) -> u32;
+    /// Returns the device ID that this file represents. Only relevant for special file.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_rdev(&self) -> u64;
+    /// Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
+    ///
+    /// The size of a symbolic link is the length of the pathname it contains,
+    /// without a terminating null byte.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_size(&self) -> u64;
+    /// Returns the last access time.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_atime(&self) -> i64;
+    /// Returns the last access time, nano seconds part.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_atime_nsec(&self) -> i64;
+    /// Returns the last modification time.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mtime(&self) -> i64;
+    /// Returns the last modification time, nano seconds part.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_mtime_nsec(&self) -> i64;
+    /// Returns the last status change time.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ctime(&self) -> i64;
+    /// Returns the last status change time, nano seconds part.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_ctime_nsec(&self) -> i64;
+    /// Returns the "preferred" blocksize for efficient filesystem I/O.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, 512-byte units.
     #[stable(feature = "metadata_ext2", since = "1.8.0")]
     fn st_blocks(&self) -> u64;
 }
diff --git a/src/libstd/os/macos/mod.rs b/src/libstd/os/macos/mod.rs
index 4e995358fd8..c9406f73100 100644
--- a/src/libstd/os/macos/mod.rs
+++ b/src/libstd/os/macos/mod.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! MacOS-specific definitions
+//! macOS-specific definitions
 
 #![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 8f9b29462c4..8ffddf638b1 100644
--- a/src/libstd/os/macos/raw.rs
+++ b/src/libstd/os/macos/raw.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! MacOS-specific raw type definitions
+//! macOS-specific raw type definitions
 
 #![stable(feature = "raw_ext", since = "1.1.0")]
 #![rustc_deprecated(since = "1.8.0",
diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw.rs
index 68d4ca90019..c34491941d6 100644
--- a/src/libstd/os/raw.rs
+++ b/src/libstd/os/raw.rs
@@ -14,22 +14,24 @@
 
 use fmt;
 
-#[cfg(any(target_os = "android",
-          target_os = "emscripten",
+#[cfg(any(target_os = "emscripten",
           all(target_os = "linux", any(target_arch = "aarch64",
                                        target_arch = "arm",
                                        target_arch = "powerpc",
                                        target_arch = "powerpc64",
                                        target_arch = "s390x")),
+          all(target_os = "android", any(target_arch = "aarch64",
+                                         target_arch = "arm")),
           all(target_os = "fuchsia", target_arch = "aarch64")))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
-#[cfg(not(any(target_os = "android",
-              target_os = "emscripten",
+#[cfg(not(any(target_os = "emscripten",
               all(target_os = "linux", any(target_arch = "aarch64",
                                            target_arch = "arm",
                                            target_arch = "powerpc",
                                            target_arch = "powerpc64",
                                            target_arch = "s390x")),
+              all(target_os = "android", any(target_arch = "aarch64",
+                                             target_arch = "arm")),
               all(target_os = "fuchsia", target_arch = "aarch64"))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 3b5a1cffc7a..6f46a73698f 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -160,10 +160,10 @@ pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
 
 /// A struct providing information about a panic.
 ///
-/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook()`]
+/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
 /// function.
 ///
-/// [`set_hook()`]: ../../std/panic/fn.set_hook.html
+/// [`set_hook`]: ../../std/panic/fn.set_hook.html
 ///
 /// # Examples
 ///
@@ -237,9 +237,9 @@ impl<'a> PanicInfo<'a> {
 
 /// A struct containing information about the location of a panic.
 ///
-/// This structure is created by the [`location()`] method of [`PanicInfo`].
+/// This structure is created by the [`location`] method of [`PanicInfo`].
 ///
-/// [`location()`]: ../../std/panic/struct.PanicInfo.html#method.location
+/// [`location`]: ../../std/panic/struct.PanicInfo.html#method.location
 /// [`PanicInfo`]: ../../std/panic/struct.PanicInfo.html
 ///
 /// # Examples
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 245a6d945b5..e128a4164d7 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -15,6 +15,13 @@
 //! around [`OsString`] and [`OsStr`] respectively, meaning that they work directly
 //! on strings according to the local platform's path syntax.
 //!
+//! Paths can be parsed into [`Component`]s by iterating over the structure
+//! returned by the [`components`] method on [`Path`]. [`Component`]s roughly
+//! correspond to the substrings between path separators (`/` or `\`). You can
+//! reconstruct an equivalent path from components with the [`push`] method on
+//! [`PathBuf`]; note that the paths may differ syntactically by the
+//! normalization described in the documentation for the [`components`] method.
+//!
 //! ## Simple usage
 //!
 //! Path manipulation includes both parsing components from slices and building
@@ -44,69 +51,26 @@
 //! ```
 //! use std::path::PathBuf;
 //!
+//! // This way works...
 //! let mut path = PathBuf::from("c:\\");
+//!
 //! path.push("windows");
 //! path.push("system32");
-//! path.set_extension("dll");
-//! ```
-//!
-//! ## Path components and normalization
-//!
-//! The path APIs are built around the notion of "components", which roughly
-//! correspond to the substrings between path separators (`/` and, on Windows,
-//! `\`). The APIs for path parsing are largely specified in terms of the path's
-//! components, so it's important to clearly understand how those are
-//! determined.
-//!
-//! A path can always be reconstructed into an *equivalent* path by
-//! putting together its components via `push`. Syntactically, the
-//! paths may differ by the normalization described below.
-//!
-//! ### Component types
-//!
-//! Components come in several types:
 //!
-//! * Normal components are the default: standard references to files or
-//! directories. The path `a/b` has two normal components, `a` and `b`.
-//!
-//! * Current directory components represent the `.` character. For example,
-//! `./a` has a current directory component and a normal component `a`.
-//!
-//! * The root directory component represents a separator that designates
-//!   starting from root. For example, `/a/b` has a root directory component
-//!   followed by normal components `a` and `b`.
-//!
-//! On Windows, an additional component type comes into play:
-//!
-//! * Prefix components, of which there is a large variety. For example, `C:`
-//! and `\\server\share` are prefixes. The path `C:windows` has a prefix
-//! component `C:` and a normal component `windows`; the path `C:\windows` has a
-//! prefix component `C:`, a root directory component, and a normal component
-//! `windows`.
-//!
-//! ### Normalization
-//!
-//! Aside from splitting on the separator(s), there is a small amount of
-//! "normalization":
-//!
-//! * Repeated separators are ignored: `a/b` and `a//b` both have components `a`
-//!   and `b`.
-//!
-//! * Occurrences of `.` are normalized away, *except* if they are at
-//! the beginning of the path (in which case they are often meaningful
-//! in terms of path searching). So, for example, `a/./b`, `a/b/`,
-//! `/a/b/.` and `a/b` all have components `a` and `b`, but `./a/b`
-//! has a leading current directory component.
+//! path.set_extension("dll");
 //!
-//! No other normalization takes place by default. In particular,
-//! `a/c` and `a/b/../c` are distinct, to account for the possibility
-//! that `b` is a symbolic link (so its parent isn't `a`). Further
-//! normalization is possible to build on top of the components APIs,
-//! and will be included in this library in the near future.
+//! // ... but push is best used if you don't know everything up
+//! // front. If you do, this way is better:
+//! let path: PathBuf = ["c:\\", "windows", "system32.dll"].iter().collect();
+//! ```
 //!
+//! [`Component`]: ../../std/path/enum.Component.html
+//! [`components`]: ../../std/path/struct.Path.html#method.components
 //! [`PathBuf`]: ../../std/path/struct.PathBuf.html
 //! [`Path`]: ../../std/path/struct.Path.html
+//! [`push`]: ../../std/path/struct.PathBuf.html#method.push
 //! [`String`]: ../../std/string/struct.String.html
+//!
 //! [`str`]: ../../std/primitive.str.html
 //! [`OsString`]: ../../std/ffi/struct.OsString.html
 //! [`OsStr`]: ../../std/ffi/struct.OsStr.html
@@ -143,36 +107,81 @@ use sys::path::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
 // Windows Prefixes
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Path prefixes (Windows only).
+/// Windows path prefixes, e.g. `C:` or `\\server\share`.
+///
+/// Windows uses a variety of path prefix styles, including references to drive
+/// volumes (like `C:`), network shared folders (like `\\server\share`), and
+/// others. In addition, some path prefixes are "verbatim" (i.e. prefixed with
+/// `\\?\`), in which case `/` is *not* treated as a separator and essentially
+/// no normalization is performed.
+///
+/// # Examples
 ///
-/// Windows uses a variety of path styles, including references to drive
-/// volumes (like `C:`), network shared folders (like `\\server\share`) and
-/// others. In addition, some path prefixes are "verbatim", in which case
-/// `/` is *not* treated as a separator and essentially no normalization is
-/// performed.
+/// ```
+/// use std::path::{Component, Path, Prefix};
+/// use std::path::Prefix::*;
+/// use std::ffi::OsStr;
+///
+/// fn get_path_prefix(s: &str) -> Prefix {
+///     let path = Path::new(s);
+///     match path.components().next().unwrap() {
+///         Component::Prefix(prefix_component) => prefix_component.kind(),
+///         _ => panic!(),
+///     }
+/// }
+///
+/// # if cfg!(windows) {
+/// assert_eq!(Verbatim(OsStr::new("pictures")),
+///            get_path_prefix(r"\\?\pictures\kittens"));
+/// assert_eq!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")),
+///            get_path_prefix(r"\\?\UNC\server\share"));
+/// assert_eq!(VerbatimDisk('C' as u8), get_path_prefix(r"\\?\c:\"));
+/// assert_eq!(DeviceNS(OsStr::new("BrainInterface")),
+///            get_path_prefix(r"\\.\BrainInterface"));
+/// assert_eq!(UNC(OsStr::new("server"), OsStr::new("share")),
+///            get_path_prefix(r"\\server\share"));
+/// assert_eq!(Disk('C' as u8), get_path_prefix(r"C:\Users\Rust\Pictures\Ferris"));
+/// # }
+/// ```
 #[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Prefix<'a> {
-    /// Prefix `\\?\`, together with the given component immediately following it.
+    /// Verbatim prefix, e.g. `\\?\cat_pics`.
+    ///
+    /// Verbatim prefixes consist of `\\?\` immediately followed by the given
+    /// component.
     #[stable(feature = "rust1", since = "1.0.0")]
     Verbatim(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 
-    /// Prefix `\\?\UNC\`, with the "server" and "share" components following it.
+    /// Verbatim prefix using Windows' _**U**niform **N**aming **C**onvention_,
+    /// e.g. `\\?\UNC\server\share`.
+    ///
+    /// Verbatim UNC prefixes consist of `\\?\UNC\` immediately followed by the
+    /// server's hostname and a share name.
     #[stable(feature = "rust1", since = "1.0.0")]
     VerbatimUNC(
         #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
         #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
     ),
 
-    /// Prefix like `\\?\C:\`, for the given drive letter
+    /// Verbatim disk prefix, e.g. `\\?\C:\`.
+    ///
+    /// Verbatim disk prefixes consist of `\\?\` immediately followed by the
+    /// drive letter and `:\`.
     #[stable(feature = "rust1", since = "1.0.0")]
     VerbatimDisk(#[stable(feature = "rust1", since = "1.0.0")] u8),
 
-    /// Prefix `\\.\`, together with the given component immediately following it.
+    /// Device namespace prefix, e.g. `\\.\COM42`.
+    ///
+    /// Device namespace prefixes consist of `\\.\` immediately followed by the
+    /// device name.
     #[stable(feature = "rust1", since = "1.0.0")]
     DeviceNS(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 
-    /// Prefix `\\server\share`, with the given "server" and "share" components.
+    /// Prefix using Windows' _**U**niform **N**aming **C**onvention_, e.g.
+    /// `\\server\share`.
+    ///
+    /// UNC prefixes consist of the server's hostname and a share name.
     #[stable(feature = "rust1", since = "1.0.0")]
     UNC(
         #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
@@ -217,6 +226,20 @@ impl<'a> Prefix<'a> {
     }
 
     /// Determines if the prefix is verbatim, i.e. begins with `\\?\`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Prefix::*;
+    /// use std::ffi::OsStr;
+    ///
+    /// assert!(Verbatim(OsStr::new("pictures")).is_verbatim());
+    /// assert!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")).is_verbatim());
+    /// assert!(VerbatimDisk('C' as u8).is_verbatim());
+    /// assert!(!DeviceNS(OsStr::new("BrainInterface")).is_verbatim());
+    /// assert!(!UNC(OsStr::new("server"), OsStr::new("share")).is_verbatim());
+    /// assert!(!Disk('C' as u8).is_verbatim());
+    /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_verbatim(&self) -> bool {
@@ -356,9 +379,42 @@ enum State {
     Done = 3,
 }
 
-/// A Windows path prefix, e.g. `C:` or `\\server\share`.
+/// A structure wrapping a Windows path prefix as well as its unparsed string
+/// representation.
+///
+/// In addition to the parsed [`Prefix`] information returned by [`kind`],
+/// `PrefixComponent` also holds the raw and unparsed [`OsStr`] slice,
+/// returned by [`as_os_str`].
+///
+/// Instances of this `struct` can be obtained by matching against the
+/// [`Prefix` variant] on [`Component`].
 ///
 /// Does not occur on Unix.
+///
+/// # Examples
+///
+/// ```
+/// # if cfg!(windows) {
+/// use std::path::{Component, Path, Prefix};
+/// use std::ffi::OsStr;
+///
+/// let path = Path::new(r"c:\you\later\");
+/// match path.components().next().unwrap() {
+///     Component::Prefix(prefix_component) => {
+///         assert_eq!(Prefix::Disk('C' as u8), prefix_component.kind());
+///         assert_eq!(OsStr::new("c:"), prefix_component.as_os_str());
+///     }
+///     _ => unreachable!(),
+/// }
+/// # }
+/// ```
+///
+/// [`as_os_str`]: #method.as_os_str
+/// [`Component`]: enum.Component.html
+/// [`kind`]: #method.kind
+/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
+/// [`Prefix` variant]: enum.Component.html#variant.Prefix
+/// [`Prefix`]: enum.Prefix.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Copy, Clone, Eq, Debug)]
 pub struct PrefixComponent<'a> {
@@ -370,13 +426,20 @@ pub struct PrefixComponent<'a> {
 }
 
 impl<'a> PrefixComponent<'a> {
-    /// The parsed prefix data.
+    /// Returns the parsed prefix data.
+    ///
+    /// See [`Prefix`]'s documentation for more information on the different
+    /// kinds of prefixes.
+    ///
+    /// [`Prefix`]: enum.Prefix.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn kind(&self) -> Prefix<'a> {
         self.parsed
     }
 
-    /// The raw `OsStr` slice for this prefix.
+    /// Returns the raw [`OsStr`] slice for this prefix.
+    ///
+    /// [`OsStr`]: ../../std/ffi/struct.OsStr.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_os_str(&self) -> &'a OsStr {
         self.raw
@@ -413,11 +476,11 @@ impl<'a> Hash for PrefixComponent<'a> {
 
 /// A single component of a path.
 ///
-/// See the module documentation for an in-depth explanation of components and
-/// their role in the API.
+/// A `Component` roughtly corresponds to a substring between path separators
+/// (`/` or `\`).
 ///
-/// This `enum` is created from iterating over the [`path::Components`]
-/// `struct`.
+/// This `enum` is created by iterating over [`Components`], which in turn is
+/// created by the [`components`][`Path::components`] method on [`Path`].
 ///
 /// # Examples
 ///
@@ -434,37 +497,49 @@ impl<'a> Hash for PrefixComponent<'a> {
 /// ]);
 /// ```
 ///
-/// [`path::Components`]: struct.Components.html
+/// [`Components`]: struct.Components.html
+/// [`Path`]: struct.Path.html
+/// [`Path::components`]: struct.Path.html#method.components
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Component<'a> {
     /// A Windows path prefix, e.g. `C:` or `\\server\share`.
     ///
+    /// There is a large variety of prefix types, see [`Prefix`]'s documentation
+    /// for more.
+    ///
     /// Does not occur on Unix.
+    ///
+    /// [`Prefix`]: enum.Prefix.html
     #[stable(feature = "rust1", since = "1.0.0")]
     Prefix(
         #[stable(feature = "rust1", since = "1.0.0")] PrefixComponent<'a>
     ),
 
-    /// The root directory component, appears after any prefix and before anything else
+    /// The root directory component, appears after any prefix and before anything else.
+    ///
+    /// It represents a separator that designates that a path starts from root.
     #[stable(feature = "rust1", since = "1.0.0")]
     RootDir,
 
-    /// A reference to the current directory, i.e. `.`
+    /// A reference to the current directory, i.e. `.`.
     #[stable(feature = "rust1", since = "1.0.0")]
     CurDir,
 
-    /// A reference to the parent directory, i.e. `..`
+    /// A reference to the parent directory, i.e. `..`.
     #[stable(feature = "rust1", since = "1.0.0")]
     ParentDir,
 
-    /// A normal component, i.e. `a` and `b` in `a/b`
+    /// A normal component, e.g. `a` and `b` in `a/b`.
+    ///
+    /// This variant is the most common one, it represents references to files
+    /// or directories.
     #[stable(feature = "rust1", since = "1.0.0")]
     Normal(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 }
 
 impl<'a> Component<'a> {
-    /// Extracts the underlying `OsStr` slice.
+    /// Extracts the underlying [`OsStr`] slice.
     ///
     /// # Examples
     ///
@@ -475,6 +550,8 @@ impl<'a> Component<'a> {
     /// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
     /// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
     /// ```
+    ///
+    /// [`OsStr`]: ../../std/ffi/struct.OsStr.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_os_str(self) -> &'a OsStr {
         match self {
@@ -494,12 +571,10 @@ impl<'a> AsRef<OsStr> for Component<'a> {
     }
 }
 
-/// The core iterator giving the components of a path.
+/// An interator over the [`Component`]s of a [`Path`].
 ///
-/// 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.
+/// This `struct` is created by the [`components`] method on [`Path`].
+/// See its documentation for more.
 ///
 /// # Examples
 ///
@@ -513,7 +588,9 @@ impl<'a> AsRef<OsStr> for Component<'a> {
 /// }
 /// ```
 ///
-/// [`path::Path::components`]: struct.Path.html#method.components
+/// [`Component`]: enum.Component.html
+/// [`components`]: struct.Path.html#method.components
+/// [`Path`]: struct.Path.html
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Components<'a> {
@@ -534,9 +611,15 @@ pub struct Components<'a> {
     back: State,
 }
 
-/// An iterator over the components of a path, as [`OsStr`] slices.
+/// An iterator over the [`Component`]s of a [`Path`], as [`OsStr`] slices.
 ///
+/// This `struct` is created by the [`iter`] method on [`Path`].
+/// See its documentation for more.
+///
+/// [`Component`]: enum.Component.html
+/// [`iter`]: struct.Path.html#method.iter
 /// [`OsStr`]: ../../std/ffi/struct.OsStr.html
+/// [`Path`]: struct.Path.html
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a> {
@@ -762,6 +845,18 @@ impl<'a> fmt::Debug for Iter<'a> {
 
 impl<'a> Iter<'a> {
     /// Extracts a slice corresponding to the portion of the path remaining for iteration.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::path::Path;
+    ///
+    /// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
+    /// iter.next();
+    /// iter.next();
+    ///
+    /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn as_path(&self) -> &'a Path {
         self.inner.as_path()
@@ -949,14 +1044,40 @@ impl<'a> cmp::Ord for Components<'a> {
 ///
 /// # Examples
 ///
+/// You can use [`push`] to build up a `PathBuf` from
+/// components:
+///
 /// ```
 /// use std::path::PathBuf;
 ///
-/// let mut path = PathBuf::from("c:\\");
+/// let mut path = PathBuf::new();
+///
+/// path.push(r"C:\");
 /// path.push("windows");
 /// path.push("system32");
+///
 /// path.set_extension("dll");
 /// ```
+///
+/// However, [`push`] is best used for dynamic situations. This is a better way
+/// to do this when you know all of the components ahead of time:
+///
+/// ```
+/// use std::path::PathBuf;
+///
+/// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
+/// ```
+///
+/// We can still do better than this! Since these are all strings, we can use
+/// `From::from`:
+///
+/// ```
+/// use std::path::PathBuf;
+///
+/// let path = PathBuf::from(r"C:\windows\system32.dll");
+/// ```
+///
+/// Which method works best depends on what kind of situation you're in.
 #[derive(Clone)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct PathBuf {
@@ -1065,13 +1186,14 @@ impl PathBuf {
         self.inner.push(path);
     }
 
-    /// Truncate `self` to [`self.parent()`].
+    /// Truncate `self` to [`self.parent`].
     ///
-    /// Returns false and does nothing if [`self.file_name()`] is `None`.
+    /// Returns `false` and does nothing if [`self.file_name`] is [`None`].
     /// Otherwise, returns `true`.
     ///
-    /// [`self.parent()`]: struct.PathBuf.html#method.parent
-    /// [`self.file_name()`]: struct.PathBuf.html#method.file_name
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    /// [`self.parent`]: struct.PathBuf.html#method.parent
+    /// [`self.file_name`]: struct.PathBuf.html#method.file_name
     ///
     /// # Examples
     ///
@@ -1096,13 +1218,18 @@ impl PathBuf {
         }
     }
 
-    /// Updates [`self.file_name()`] to `file_name`.
+    /// Updates [`self.file_name`] to `file_name`.
     ///
-    /// If [`self.file_name()`] was [`None`], this is equivalent to pushing
+    /// If [`self.file_name`] was [`None`], this is equivalent to pushing
     /// `file_name`.
     ///
-    /// [`self.file_name()`]: struct.PathBuf.html#method.file_name
+    /// Otherwise it is equivalent to calling [`pop`] and then pushing
+    /// `file_name`. The new path will be a sibling of the original path.
+    /// (That is, it will have the same parent.)
+    ///
+    /// [`self.file_name`]: struct.PathBuf.html#method.file_name
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    /// [`pop`]: struct.PathBuf.html#method.pop
     ///
     /// # Examples
     ///
@@ -1130,15 +1257,16 @@ impl PathBuf {
         self.push(file_name);
     }
 
-    /// Updates [`self.extension()`] to `extension`.
+    /// Updates [`self.extension`] to `extension`.
     ///
-    /// If [`self.file_name()`] is `None`, does nothing and returns `false`.
+    /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
+    /// returns `true` and updates the extension otherwise.
     ///
-    /// Otherwise, returns `true`; if [`self.extension()`] is [`None`], the
-    /// extension is added; otherwise it is replaced.
+    /// If [`self.extension`] is [`None`], the extension is added; otherwise
+    /// it is replaced.
     ///
-    /// [`self.file_name()`]: struct.PathBuf.html#method.file_name
-    /// [`self.extension()`]: struct.PathBuf.html#method.extension
+    /// [`self.file_name`]: struct.PathBuf.html#method.file_name
+    /// [`self.extension`]: struct.PathBuf.html#method.extension
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
@@ -1195,8 +1323,11 @@ impl PathBuf {
         self.inner
     }
 
-    /// Converts this `PathBuf` into a boxed `Path`.
-    #[unstable(feature = "into_boxed_path", issue = "0")]
+    /// Converts this `PathBuf` into a [boxed][`Box`] [`Path`].
+    ///
+    /// [`Box`]: ../../std/boxed/struct.Box.html
+    /// [`Path`]: struct.Path.html
+    #[unstable(feature = "into_boxed_path", issue = "40380")]
     pub fn into_boxed_path(self) -> Box<Path> {
         unsafe { mem::transmute(self.inner.into_boxed_os_str()) }
     }
@@ -1210,11 +1341,17 @@ impl<'a> From<&'a Path> for Box<Path> {
     }
 }
 
-#[stable(feature = "box_default_extra", since = "1.17.0")]
-impl Default for Box<Path> {
-    fn default() -> Box<Path> {
-        let boxed: Box<OsStr> = Default::default();
-        unsafe { mem::transmute(boxed) }
+#[stable(feature = "path_buf_from_box", since = "1.18.0")]
+impl From<Box<Path>> for PathBuf {
+    fn from(boxed: Box<Path>) -> PathBuf {
+        boxed.into_path_buf()
+    }
+}
+
+#[stable(feature = "box_from_path_buf", since = "1.18.0")]
+impl Into<Box<Path>> for PathBuf {
+    fn into(self) -> Box<Path> {
+        self.into_boxed_path()
     }
 }
 
@@ -1287,7 +1424,7 @@ impl Borrow<Path> for PathBuf {
     }
 }
 
-#[stable(feature = "default_for_pathbuf", since = "1.16.0")]
+#[stable(feature = "default_for_pathbuf", since = "1.17.0")]
 impl Default for PathBuf {
     fn default() -> Self {
         PathBuf::new()
@@ -1316,6 +1453,9 @@ impl ToOwned for Path {
     fn to_owned(&self) -> PathBuf {
         self.to_path_buf()
     }
+    fn clone_into(&self, target: &mut PathBuf) {
+        self.inner.clone_into(&mut target.inner);
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1396,10 +1536,14 @@ pub struct Path {
     inner: OsStr,
 }
 
-/// An error returned from the [`Path::strip_prefix`] method indicating that the
-/// prefix was not found in `self`.
+/// An error returned from [`Path::strip_prefix`][`strip_prefix`] if the prefix
+/// was not found.
+///
+/// This `struct` is created by the [`strip_prefix`] method on [`Path`].
+/// See its documentation for more.
 ///
-/// [`Path::strip_prefix`]: struct.Path.html#method.strip_prefix
+/// [`strip_prefix`]: struct.Path.html#method.strip_prefix
+/// [`Path`]: struct.Path.html
 #[derive(Debug, Clone, PartialEq, Eq)]
 #[stable(since = "1.7.0", feature = "strip_prefix")]
 pub struct StripPrefixError(());
@@ -1415,7 +1559,7 @@ impl Path {
         os_str_as_u8_slice(&self.inner)
     }
 
-    /// Directly wrap a string slice as a `Path` slice.
+    /// Directly wraps a string slice as a `Path` slice.
     ///
     /// This is a cost-free conversion.
     ///
@@ -1495,7 +1639,7 @@ impl Path {
     /// assert_eq!(path.to_string_lossy(), "foo.txt");
     /// ```
     ///
-    /// Had `os_str` contained invalid unicode, the `to_string_lossy` call might
+    /// Had `path` contained invalid unicode, the `to_string_lossy` call might
     /// have returned `"fo�.txt"`.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn to_string_lossy(&self) -> Cow<str> {
@@ -1519,10 +1663,11 @@ impl Path {
         PathBuf::from(self.inner.to_os_string())
     }
 
-    /// A path is *absolute* if it is independent of the current directory.
+    /// Returns `true` if the `Path` is absolute, i.e. if it is independent of
+    /// the current directory.
     ///
     /// * On Unix, a path is absolute if it starts with the root, so
-    /// `is_absolute` and `has_root` are equivalent.
+    /// `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.
@@ -1534,6 +1679,8 @@ impl Path {
     ///
     /// assert!(!Path::new("foo.txt").is_absolute());
     /// ```
+    ///
+    /// [`has_root`]: #method.has_root
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow(deprecated)]
     pub fn is_absolute(&self) -> bool {
@@ -1541,7 +1688,9 @@ impl Path {
         self.has_root() && (cfg!(unix) || cfg!(target_os = "redox") || self.prefix().is_some())
     }
 
-    /// A path is *relative* if it is not absolute.
+    /// Return `false` if the `Path` is relative, i.e. not absolute.
+    ///
+    /// See [`is_absolute`]'s documentation for more details.
     ///
     /// # Examples
     ///
@@ -1550,6 +1699,8 @@ impl Path {
     ///
     /// assert!(Path::new("foo.txt").is_relative());
     /// ```
+    ///
+    /// [`is_absolute`]: #method.is_absolute
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_relative(&self) -> bool {
         !self.is_absolute()
@@ -1559,7 +1710,7 @@ impl Path {
         self.components().prefix
     }
 
-    /// A path has a root if the body of the path begins with the directory separator.
+    /// Returns `true` if the `Path` has a root.
     ///
     /// * On Unix, a path has a root if it begins with `/`.
     ///
@@ -1580,7 +1731,7 @@ impl Path {
         self.components().has_root()
     }
 
-    /// The path without its final component, if any.
+    /// Returns the `Path` without its final component, if there is one.
     ///
     /// Returns [`None`] if the path terminates in a root or prefix.
     ///
@@ -1613,9 +1764,12 @@ impl Path {
         })
     }
 
-    /// The final component of the path, if it is a normal file.
+    /// Returns the final component of the `Path`, if there is one.
+    ///
+    /// If the path is a normal file, this is the file name. If it's the path of a directory, this
+    /// is the directory name.
     ///
-    /// If the path terminates in `..`, `file_name` will return [`None`].
+    /// Returns [`None`] If the path terminates in `..`.
     ///
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
@@ -1625,21 +1779,12 @@ impl Path {
     /// use std::path::Path;
     /// use std::ffi::OsStr;
     ///
-    /// let path = Path::new("foo.txt");
-    /// let os_str = OsStr::new("foo.txt");
-    ///
-    /// assert_eq!(Some(os_str), path.file_name());
-    /// ```
-    ///
-    /// # Other examples
-    ///
-    /// ```
-    /// use std::path::Path;
-    /// use std::ffi::OsStr;
-    ///
+    /// assert_eq!(Some(OsStr::new("bin")), Path::new("/usr/bin/").file_name());
+    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("tmp/foo.txt").file_name());
     /// 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());
+    /// assert_eq!(None, Path::new("/").file_name());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn file_name(&self) -> Option<&OsStr> {
@@ -1733,9 +1878,9 @@ impl Path {
         iter_after(self.components().rev(), child.components().rev()).is_some()
     }
 
-    /// Extracts the stem (non-extension) portion of [`self.file_name()`].
+    /// Extracts the stem (non-extension) portion of [`self.file_name`].
     ///
-    /// [`self.file_name()`]: struct.Path.html#method.file_name
+    /// [`self.file_name`]: struct.Path.html#method.file_name
     ///
     /// The stem is:
     ///
@@ -1760,7 +1905,7 @@ impl Path {
         self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.or(after))
     }
 
-    /// Extracts the extension of [`self.file_name()`], if possible.
+    /// Extracts the extension of [`self.file_name`], if possible.
     ///
     /// The extension is:
     ///
@@ -1769,7 +1914,7 @@ impl Path {
     /// * [`None`], if the file name begins with `.` and has no other `.`s within;
     /// * Otherwise, the portion of the file name after the final `.`
     ///
-    /// [`self.file_name()`]: struct.Path.html#method.file_name
+    /// [`self.file_name`]: struct.Path.html#method.file_name
     /// [`None`]: ../../std/option/enum.Option.html#variant.None
     ///
     /// # Examples
@@ -1825,6 +1970,9 @@ impl Path {
     ///
     /// let path = Path::new("/tmp/foo.txt");
     /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
+    ///
+    /// let path = Path::new("/tmp");
+    /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
@@ -1863,7 +2011,21 @@ impl Path {
         buf
     }
 
-    /// Produce an iterator over the components of the path.
+    /// Produces an iterator over the [`Component`]s of the path.
+    ///
+    /// When parsing the path, there is a small amount of normalization:
+    ///
+    /// * Repeated separators are ignored, so `a/b` and `a//b` both have
+    ///   `a` and `b` as components.
+    ///
+    /// * Occurentces of `.` are normalized away, exept if they are at the
+    ///   beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
+    ///   `a/b` all have `a` and `b` as components, but `./a/b` starts with
+    ///   an additional [`CurDir`] component.
+    ///
+    /// Note that no other normalization takes place; in particular, `a/c`
+    /// and `a/b/../c` are distinct, to account for the possibility that `b`
+    /// is a symbolic link (so its parent isn't `a`).
     ///
     /// # Examples
     ///
@@ -1878,6 +2040,9 @@ impl Path {
     /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("foo.txt"))));
     /// assert_eq!(components.next(), None)
     /// ```
+    ///
+    /// [`Component`]: enum.Component.html
+    /// [`CurDir`]: enum.Component.html#variant.CurDir
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn components(&self) -> Components {
         let prefix = parse_prefix(self.as_os_str());
@@ -1890,8 +2055,13 @@ impl Path {
         }
     }
 
-    /// Produce an iterator over the path's components viewed as [`OsStr`] slices.
+    /// Produces an iterator over the path's components viewed as [`OsStr`]
+    /// slices.
+    ///
+    /// For more information about the particulars of how the path is separated
+    /// into components, see [`components`].
     ///
+    /// [`components`]: #method.components
     /// [`OsStr`]: ../ffi/struct.OsStr.html
     ///
     /// # Examples
@@ -1930,7 +2100,7 @@ impl Path {
         Display { path: self }
     }
 
-    /// Query the file system to get information about a file, directory, etc.
+    /// Queries the file system to get information about a file, directory, etc.
     ///
     /// This function will traverse symbolic links to query information about the
     /// destination file.
@@ -1953,7 +2123,7 @@ impl Path {
         fs::metadata(self)
     }
 
-    /// Query the metadata about a file without following symlinks.
+    /// Queries the metadata about a file without following symlinks.
     ///
     /// This is an alias to [`fs::symlink_metadata`].
     ///
@@ -2089,6 +2259,17 @@ impl Path {
     pub fn is_dir(&self) -> bool {
         fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
     }
+
+    /// Converts a [`Box<Path>`][`Box`] into a [`PathBuf`] without copying or
+    /// allocating.
+    ///
+    /// [`Box`]: ../../std/boxed/struct.Box.html
+    /// [`PathBuf`]: struct.PathBuf.html
+    #[unstable(feature = "into_boxed_path", issue = "40380")]
+    pub fn into_path_buf(self: Box<Path>) -> PathBuf {
+        let inner: Box<OsStr> = unsafe { mem::transmute(self) };
+        PathBuf { inner: OsString::from(inner) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2105,7 +2286,26 @@ impl fmt::Debug for Path {
     }
 }
 
-/// Helper struct for safely printing paths with `format!()` and `{}`
+/// Helper struct for safely printing paths with [`format!`] and `{}`.
+///
+/// A [`Path`] might contain non-Unicode data. This `struct` implements the
+/// [`Display`] trait in a way that mitigates that. It is created by the
+/// [`display`][`Path::display`] method on [`Path`].
+///
+/// # Examples
+///
+/// ```
+/// use std::path::Path;
+///
+/// let path = Path::new("/tmp/foo.rs");
+///
+/// println!("{}", path.display());
+/// ```
+///
+/// [`Display`]: ../../std/fmt/trait.Display.html
+/// [`format!`]: ../../std/macro.format.html
+/// [`Path`]: struct.Path.html
+/// [`Path::display`]: struct.Path.html#method.display
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Display<'a> {
     path: &'a Path,
@@ -3703,17 +3903,19 @@ mod tests {
     fn into_boxed() {
         let orig: &str = "some/sort/of/path";
         let path = Path::new(orig);
-        let path_buf = path.to_owned();
-        let box1: Box<Path> = Box::from(path);
-        let box2 = path_buf.into_boxed_path();
-        assert_eq!(path, &*box1);
-        assert_eq!(box1, box2);
-        assert_eq!(&*box2, path);
+        let boxed: Box<Path> = Box::from(path);
+        let path_buf = path.to_owned().into_boxed_path().into_path_buf();
+        assert_eq!(path, &*boxed);
+        assert_eq!(&*boxed, &*path_buf);
+        assert_eq!(&*path_buf, path);
     }
 
     #[test]
-    fn boxed_default() {
-        let boxed = <Box<Path>>::default();
-        assert!(boxed.as_os_str().is_empty());
+    fn test_clone_into() {
+        let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
+        let path = Path::new("short");
+        path.clone_into(&mut path_buf);
+        assert_eq!(path, path_buf);
+        assert!(path_buf.into_os_string().capacity() >= 15);
     }
 }
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index f4cd319f064..86e661d7948 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -56,14 +56,14 @@
 //!   traits indicate fundamental properties of types.
 //! * [`std::ops`]::{[`Drop`], [`Fn`], [`FnMut`], [`FnOnce`]}. Various
 //!   operations for both destructors and overloading `()`.
-//! * [`std::mem`]::[`drop`], a convenience function for explicitly dropping a
-//!   value.
+//! * [`std::mem`]::[`drop`][`mem::drop`], a convenience function for explicitly
+//!   dropping a value.
 //! * [`std::boxed`]::[`Box`], a way to allocate values on the heap.
 //! * [`std::borrow`]::[`ToOwned`], The conversion trait that defines
-//!   [`to_owned()`], the generic method for creating an owned type from a
+//!   [`to_owned`], the generic method for creating an owned type from a
 //!   borrowed type.
-//! * [`std::clone`]::[`Clone`], the ubiquitous trait that defines [`clone()`],
-//!   the method for producing a copy of a value.
+//! * [`std::clone`]::[`Clone`], the ubiquitous trait that defines
+//!   [`clone`][`Clone::clone`], the method for producing a copy of a value.
 //! * [`std::cmp`]::{[`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] }. The
 //!   comparison traits, which implement the comparison operators and are often
 //!   seen in trait bounds.
@@ -117,8 +117,8 @@
 //! [`ToOwned`]: ../borrow/trait.ToOwned.html
 //! [`ToString`]: ../string/trait.ToString.html
 //! [`Vec`]: ../vec/struct.Vec.html
-//! [`clone()`]: ../clone/trait.Clone.html#tymethod.clone
-//! [`drop`]: ../mem/fn.drop.html
+//! [`Clone::clone`]: ../clone/trait.Clone.html#tymethod.clone
+//! [`mem::drop`]: ../mem/fn.drop.html
 //! [`std::borrow`]: ../borrow/index.html
 //! [`std::boxed`]: ../boxed/index.html
 //! [`std::clone`]: ../clone/index.html
@@ -135,7 +135,7 @@
 //! [`std::slice`]: ../slice/index.html
 //! [`std::string`]: ../string/index.html
 //! [`std::vec`]: ../vec/index.html
-//! [`to_owned()`]: ../borrow/trait.ToOwned.html#tymethod.to_owned
+//! [`to_owned`]: ../borrow/trait.ToOwned.html#tymethod.to_owned
 //! [book-closures]: ../../book/closures.html
 //! [book-dtor]: ../../book/drop.html
 //! [book-enums]: ../../book/enums.html
diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index 11197db98a3..61ff8daddf0 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -29,7 +29,7 @@
 /// ```
 ///
 /// [`assert!`]: macro.assert.html
-/// [`if`]: ../book/if.html
+/// [`if`]: ../book/first-edition/if.html
 /// [`BitAnd`]: ops/trait.BitAnd.html
 /// [`BitOr`]: ops/trait.BitOr.html
 /// [`Not`]: ops/trait.Not.html
@@ -183,9 +183,9 @@ mod prim_unit { }
 /// Working with raw pointers in Rust is uncommon,
 /// typically limited to a few patterns.
 ///
-/// Use the `null` function to create null pointers, and the `is_null` method
+/// Use the [`null`] function to create null pointers, and the [`is_null`] method
 /// of the `*const T` type  to check for null. The `*const T` type also defines
-/// the `offset` method, for pointer math.
+/// the [`offset`] method, for pointer math.
 ///
 /// # Common ways to create raw pointers
 ///
@@ -213,7 +213,7 @@ mod prim_unit { }
 ///
 /// ## 2. Consume a box (`Box<T>`).
 ///
-/// The `into_raw` function consumes a box and returns
+/// The [`into_raw`] function consumes a box and returns
 /// the raw pointer. It doesn't destroy `T` or deallocate any memory.
 ///
 /// ```
@@ -227,7 +227,7 @@ mod prim_unit { }
 /// }
 /// ```
 ///
-/// Note that here the call to `drop` is for clarity - it indicates
+/// Note that here the call to [`drop`] is for clarity - it indicates
 /// that we are done with the given value and it should be destroyed.
 ///
 /// ## 3. Get it from C.
@@ -255,6 +255,11 @@ mod prim_unit { }
 ///
 /// *[See also the `std::ptr` module](ptr/index.html).*
 ///
+/// [`null`]: ../std/ptr/fn.null.html
+/// [`is_null`]: ../std/primitive.pointer.html#method.is_null
+/// [`offset`]: ../std/primitive.pointer.html#method.offset
+/// [`into_raw`]: ../std/boxed/struct.Box.html#method.into_raw
+/// [`drop`]: ../std/mem/fn.drop.html
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_pointer { }
 
@@ -272,7 +277,7 @@ mod prim_pointer { }
 /// Arrays of sizes from 0 to 32 (inclusive) implement the following traits if
 /// the element type allows it:
 ///
-/// - [`Clone`][clone] (only if `T: [Copy][copy]`)
+/// - [`Clone`][clone] (only if `T: `[`Copy`][copy])
 /// - [`Debug`][debug]
 /// - [`IntoIterator`][intoiterator] (implemented for `&[T; N]` and `&mut [T; N]`)
 /// - [`PartialEq`][partialeq], [`PartialOrd`][partialord], [`Eq`][eq], [`Ord`][ord]
@@ -401,7 +406,7 @@ mod prim_slice { }
 ///
 /// This documentation describes a number of methods and trait implementations
 /// on the `str` type. For technical reasons, there is additional, separate
-/// documentation in [the `std::str` module](str/index.html) as well.
+/// documentation in the [`std::str`](str/index.html) module as well.
 ///
 /// # Examples
 ///
@@ -420,7 +425,7 @@ mod prim_slice { }
 /// # Representation
 ///
 /// A `&str` is made up of two components: a pointer to some bytes, and a
-/// length. You can look at these with the [`.as_ptr()`] and [`len()`] methods:
+/// length. You can look at these with the [`as_ptr`] and [`len`] methods:
 ///
 /// ```
 /// use std::slice;
@@ -447,11 +452,11 @@ mod prim_slice { }
 /// assert_eq!(s, Ok(story));
 /// ```
 ///
-/// [`.as_ptr()`]: #method.as_ptr
-/// [`len()`]: #method.len
+/// [`as_ptr`]: #method.as_ptr
+/// [`len`]: #method.len
 ///
 /// Note: This example shows the internals of `&str`. `unsafe` should not be
-/// used to get a string slice under normal circumstances. Use `.as_slice()`
+/// used to get a string slice under normal circumstances. Use `as_slice`
 /// instead.
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_str { }
@@ -490,7 +495,7 @@ mod prim_str { }
 /// assert_eq!(tuple.2, 'c');
 /// ```
 ///
-/// For more about tuples, see [the book](../book/primitive-types.html#tuples).
+/// For more about tuples, see [the book](../book/first-edition/primitive-types.html#tuples).
 ///
 /// # Trait implementations
 ///
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index f846ef3e69e..da64704efba 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -73,6 +73,15 @@ use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// spawning process and can itself be constructed using a builder-style
 /// interface.
 ///
+/// 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`](#method.wait) (or other functions that wrap around it) will make
+/// the parent process wait until the child has actually exited before
+/// continuing.
+///
 /// # Examples
 ///
 /// ```should_panic
@@ -89,17 +98,6 @@ use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// assert!(ecode.success());
 /// ```
 ///
-/// # Note
-///
-/// 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`][`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
@@ -150,8 +148,9 @@ impl fmt::Debug for Child {
     }
 }
 
-/// A handle to a child process's stdin. This struct is used in the [`stdin`]
-/// field on [`Child`].
+/// 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
@@ -192,8 +191,9 @@ impl fmt::Debug for ChildStdin {
     }
 }
 
-/// A handle to a child process's stdout. This struct is used in the [`stdout`]
-/// field on [`Child`].
+/// 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
@@ -233,8 +233,9 @@ impl fmt::Debug for ChildStdout {
     }
 }
 
-/// A handle to a child process's stderr. This struct is used in the [`stderr`]
-/// field on [`Child`].
+/// 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
@@ -343,6 +344,23 @@ impl Command {
 
     /// Add an argument to pass to the program.
     ///
+    /// Only one argument can be passed per use. So instead of:
+    ///
+    /// ```ignore
+    /// .arg("-C /path/to/repo")
+    /// ```
+    ///
+    /// usage would be:
+    ///
+    /// ```ignore
+    /// .arg("-C")
+    /// .arg("/path/to/repo")
+    /// ```
+    ///
+    /// To pass multiple arguments see [`args`].
+    ///
+    /// [`args`]: #method.args
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -364,6 +382,10 @@ impl Command {
 
     /// Add multiple arguments to pass to the program.
     ///
+    /// To pass a single argument see [`arg`].
+    ///
+    /// [`arg`]: #method.arg
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -416,7 +438,10 @@ impl Command {
     /// # Examples
     ///
     /// Basic usage:
+    ///
     /// ```no_run
+    /// #![feature(command_envs)]
+    ///
     /// use std::process::{Command, Stdio};
     /// use std::env;
     /// use std::collections::HashMap;
@@ -729,6 +754,13 @@ impl fmt::Debug for Stdio {
 }
 
 /// Describes the result of a process after it has terminated.
+///
+/// This `struct` is used to represent the exit status of a child process.
+/// Child processes are created via the [`Command`] struct and their exit
+/// status is exposed through the [`status`] method.
+///
+/// [`Command`]: struct.Command.html
+/// [`status`]: struct.Command.html#method.status
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "process", since = "1.0.0")]
 pub struct ExitStatus(imp::ExitStatus);
@@ -763,6 +795,22 @@ impl ExitStatus {
     /// On Unix, this will return `None` if the process was terminated
     /// by a signal; `std::os::unix` provides an extension trait for
     /// extracting the signal and other details from the `ExitStatus`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::process::Command;
+    ///
+    /// let status = Command::new("mkdir")
+    ///                      .arg("projects")
+    ///                      .status()
+    ///                      .expect("failed to execute mkdir");
+    ///
+    /// match status.code() {
+    ///     Some(code) => println!("Exited with status code: {}", code),
+    ///     None       => println!("Process terminated by signal")
+    /// }
+    /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn code(&self) -> Option<i32> {
         self.0.code()
@@ -880,8 +928,6 @@ impl Child {
     /// Basic usage:
     ///
     /// ```no_run
-    /// #![feature(process_try_wait)]
-    ///
     /// use std::process::Command;
     ///
     /// let mut child = Command::new("ls").spawn().unwrap();
@@ -896,7 +942,7 @@ impl Child {
     ///     Err(e) => println!("error attempting to wait: {}", e),
     /// }
     /// ```
-    #[unstable(feature = "process_try_wait", issue = "38903")]
+    #[stable(feature = "process_try_wait", since = "1.18.0")]
     pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
         Ok(self.handle.try_wait()?.map(ExitStatus))
     }
@@ -1012,7 +1058,7 @@ impl Child {
 /// ```no_run
 /// use std::process;
 ///
-/// process::exit(0x0f00);
+/// process::exit(0x0100);
 /// ```
 ///
 /// [platform-specific behavior]: #platform-specific-behavior
@@ -1032,7 +1078,42 @@ pub fn exit(code: i32) -> ! {
 /// will be run. If a clean shutdown is needed it is recommended to only call
 /// this function at a known point where there are no more destructors left
 /// to run.
-#[unstable(feature = "process_abort", issue = "37838")]
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::process;
+///
+/// fn main() {
+///     println!("aborting");
+///
+///     process::abort();
+///
+///     // execution never gets here
+/// }
+/// ```
+///
+/// The [`abort`] function terminates the process, so the destructor will not
+/// get run on the example below:
+///
+/// ```no_run
+/// use std::process;
+///
+/// struct HasDrop;
+///
+/// impl Drop for HasDrop {
+///     fn drop(&mut self) {
+///         println!("This will never be printed!");
+///     }
+/// }
+///
+/// fn main() {
+///     let _x = HasDrop;
+///     process::abort();
+///     // the destructor implemented for HasDrop will never get run
+/// }
+/// ```
+#[stable(feature = "process_abort", since = "1.17.0")]
 pub fn abort() -> ! {
     unsafe { ::sys::abort_internal() };
 }
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index b853e83de5d..4f33d726398 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -52,7 +52,7 @@
 //!     If an application does not have `getrandom` and likely to be run soon after first booting,
 //!     or on a system with very few entropy sources, one should consider using `/dev/random` via
 //!     `ReaderRng`.
-//! -   On some systems (e.g. FreeBSD, OpenBSD and Mac OS X) there is no difference
+//! -   On some systems (e.g. FreeBSD, OpenBSD and macOS) there is no difference
 //!     between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random`
 //!     and `/dev/urandom` may block once if the CSPRNG has not seeded yet.)
 
@@ -195,7 +195,7 @@ impl Rng for ThreadRng {
 /// A random number generator that retrieves randomness straight from
 /// the operating system. Platform sources:
 ///
-/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
+/// - Unix-like systems (Linux, Android, macOS): read directly from
 ///   `/dev/urandom`, or from `getrandom(2)` system call if available.
 /// - Windows: calls `CryptGenRandom`, using the default cryptographic
 ///   service provider with the `PROV_RSA_FULL` type.
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index 78d5aa597ba..06fd838ea06 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -29,13 +29,14 @@ pub use panicking::{begin_panic, begin_panic_fmt, update_panic_count};
 
 #[cfg(not(test))]
 #[lang = "start"]
-fn lang_start(main: *const u8, argc: isize, argv: *const *const u8) -> isize {
-    use mem;
+fn lang_start(main: fn(), argc: isize, argv: *const *const u8) -> isize {
     use panic;
     use sys;
     use sys_common;
-    use sys_common::thread_info::{self, NewThread};
+    use sys_common::thread_info;
     use thread::Thread;
+    #[cfg(not(feature = "backtrace"))]
+    use mem;
 
     sys::init();
 
@@ -47,13 +48,18 @@ 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::new(Some("main".to_owned()));
         thread_info::set(main_guard, thread);
 
         // Store our args if necessary in a squirreled away location
         sys::args::init(argc, argv);
 
         // Let's run some code!
+        #[cfg(feature = "backtrace")]
+        let res = panic::catch_unwind(|| {
+            ::sys_common::backtrace::__rust_begin_short_backtrace(main)
+        });
+        #[cfg(not(feature = "backtrace"))]
         let res = panic::catch_unwind(mem::transmute::<_, fn()>(main));
         sys_common::cleanup();
         res.is_err()
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs
index f15e7ff8916..a7b01e49d2b 100644
--- a/src/libstd/sync/barrier.rs
+++ b/src/libstd/sync/barrier.rs
@@ -50,12 +50,11 @@ struct BarrierState {
     generation_id: usize,
 }
 
-/// A result returned from wait.
+/// A `BarrierWaitResult` is returned by [`wait`] when all threads in the [`Barrier`]
+/// have rendezvoused.
 ///
-/// Currently this opaque structure only has one method, [`.is_leader()`]. Only
-/// one thread will receive a result that will return `true` from this function.
-///
-/// [`.is_leader()`]: #method.is_leader
+/// [`wait`]: struct.Barrier.html#method.wait
+/// [`Barrier`]: struct.Barrier.html
 ///
 /// # Examples
 ///
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index 68c7e88f67f..c120a3045e4 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -150,7 +150,7 @@ impl Condvar {
     ///
     /// This function will atomically unlock the mutex specified (represented by
     /// `guard`) and block the current thread. This means that any calls
-    /// to [`notify_one()`] or [`notify_all()`] which happen logically after the
+    /// to [`notify_one`] or [`notify_all`] which happen logically after the
     /// mutex is unlocked are candidates to wake this thread up. When this
     /// function call returns, the lock specified will have been re-acquired.
     ///
@@ -167,16 +167,16 @@ impl Condvar {
     ///
     /// # Panics
     ///
-    /// This function will [`panic!()`] if it is used with more than one mutex
+    /// This function will [`panic!`] if it is used with more than one mutex
     /// over time. Each condition variable is dynamically bound to exactly one
     /// mutex to ensure defined behavior across platforms. If this functionality
     /// is not desired, then unsafe primitives in `sys` are provided.
     ///
-    /// [`notify_one()`]: #method.notify_one
-    /// [`notify_all()`]: #method.notify_all
+    /// [`notify_one`]: #method.notify_one
+    /// [`notify_all`]: #method.notify_all
     /// [poisoning]: ../sync/struct.Mutex.html#poisoning
     /// [`Mutex`]: ../sync/struct.Mutex.html
-    /// [`panic!()`]: ../../std/macro.panic.html
+    /// [`panic!`]: ../../std/macro.panic.html
     ///
     /// # Examples
     ///
@@ -359,11 +359,11 @@ impl Condvar {
     /// be woken up from its call to [`wait`] or [`wait_timeout`]. Calls to
     /// `notify_one` are not buffered in any way.
     ///
-    /// To wake up all threads, see [`notify_all()`].
+    /// To wake up all threads, see [`notify_all`].
     ///
     /// [`wait`]: #method.wait
     /// [`wait_timeout`]: #method.wait_timeout
-    /// [`notify_all()`]: #method.notify_all
+    /// [`notify_all`]: #method.notify_all
     ///
     /// # Examples
     ///
@@ -401,9 +401,9 @@ impl Condvar {
     /// variable are awoken. Calls to `notify_all()` are not buffered in any
     /// way.
     ///
-    /// To wake up only one thread, see [`notify_one()`].
+    /// To wake up only one thread, see [`notify_one`].
     ///
-    /// [`notify_one()`]: #method.notify_one
+    /// [`notify_one`]: #method.notify_one
     ///
     /// # Examples
     ///
@@ -461,7 +461,7 @@ impl fmt::Debug for Condvar {
     }
 }
 
-#[stable(feature = "condvar_default", since = "1.9.0")]
+#[stable(feature = "condvar_default", since = "1.10.0")]
 impl Default for Condvar {
     /// Creates a `Condvar` which is ready to be waited on and notified.
     fn default() -> Condvar {
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index aeeab170dea..69507cada2b 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -13,40 +13,50 @@
 //! This module provides message-based communication over channels, concretely
 //! defined among three types:
 //!
-//! * `Sender`
-//! * `SyncSender`
-//! * `Receiver`
+//! * [`Sender`]
+//! * [`SyncSender`]
+//! * [`Receiver`]
 //!
-//! A `Sender` or `SyncSender` is used to send data to a `Receiver`. Both
+//! A [`Sender`] or [`SyncSender`] is used to send data to a [`Receiver`]. Both
 //! senders are clone-able (multi-producer) such that many threads can send
 //! simultaneously to one receiver (single-consumer).
 //!
 //! These channels come in two flavors:
 //!
-//! 1. An asynchronous, infinitely buffered channel. The `channel()` function
+//! 1. An asynchronous, infinitely buffered channel. The [`channel`] function
 //!    will return a `(Sender, Receiver)` tuple where all sends will be
 //!    **asynchronous** (they never block). The channel conceptually has an
 //!    infinite buffer.
 //!
-//! 2. A synchronous, bounded channel. The `sync_channel()` function will return
-//!    a `(SyncSender, Receiver)` tuple where the storage for pending messages
-//!    is a pre-allocated buffer of a fixed size. All sends will be
+//! 2. A synchronous, bounded channel. The [`sync_channel`] function will
+//!    return a `(SyncSender, Receiver)` tuple where the storage for pending
+//!    messages is a pre-allocated buffer of a fixed size. All sends will be
 //!    **synchronous** by blocking until there is buffer space available. Note
-//!    that a bound of 0 is allowed, causing the channel to become a
-//!    "rendezvous" channel where each sender atomically hands off a message to
-//!    a receiver.
+//!    that a bound of 0 is allowed, causing the channel to become a "rendezvous"
+//!    channel where each sender atomically hands off a message to a receiver.
+//!
+//! [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
+//! [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html
+//! [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
+//! [`send`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
+//! [`channel`]: ../../../std/sync/mpsc/fn.channel.html
+//! [`sync_channel`]: ../../../std/sync/mpsc/fn.sync_channel.html
 //!
 //! ## Disconnection
 //!
-//! The send and receive operations on channels will all return a `Result`
+//! The send and receive operations on channels will all return a [`Result`]
 //! indicating whether the operation succeeded or not. An unsuccessful operation
 //! is normally indicative of the other half of a channel having "hung up" by
 //! being dropped in its corresponding thread.
 //!
 //! Once half of a channel has been deallocated, most operations can no longer
-//! continue to make progress, so `Err` will be returned. Many applications will
-//! continue to `unwrap()` the results returned from this module, instigating a
-//! propagation of failure among threads if one unexpectedly dies.
+//! continue to make progress, so [`Err`] will be returned. Many applications
+//! will continue to [`unwrap`] the results returned from this module,
+//! instigating a propagation of failure among threads if one unexpectedly dies.
+//!
+//! [`Result`]: ../../../std/result/enum.Result.html
+//! [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+//! [`unwrap`]: ../../../std/result/enum.Result.html#method.unwrap
 //!
 //! # Examples
 //!
@@ -287,8 +297,34 @@ mod sync;
 mod mpsc_queue;
 mod spsc_queue;
 
-/// The receiving-half of Rust's channel type. This half can only be owned by
-/// one thread
+/// The receiving half of Rust's [`channel`][] (or [`sync_channel`]) type.
+/// This half can only be owned by one thread.
+///
+/// Messages sent to the channel can be retrieved using [`recv`].
+///
+/// [`channel`]: fn.channel.html
+/// [`sync_channel`]: fn.sync_channel.html
+/// [`recv`]: struct.Receiver.html#method.recv
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let (send, recv) = channel();
+///
+/// thread::spawn(move || {
+///     send.send("Hello world!").unwrap();
+///     thread::sleep(Duration::from_secs(2)); // block for two seconds
+///     send.send("Delayed for 2 seconds").unwrap();
+/// });
+///
+/// println!("{}", recv.recv().unwrap()); // Received immediately
+/// println!("Waiting...");
+/// println!("{}", recv.recv().unwrap()); // Received after 2 seconds
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Receiver<T> {
     inner: UnsafeCell<Flavor<T>>,
@@ -302,38 +338,153 @@ unsafe impl<T: Send> Send for Receiver<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for Receiver<T> { }
 
-/// An 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.
+/// An iterator over messages on a [`Receiver`], created by [`iter`].
+///
+/// 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.
+///
+/// [`iter`]: struct.Receiver.html#method.iter
+/// [`Receiver`]: struct.Receiver.html
+/// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next
+/// [`None`]: ../../../std/option/enum.Option.html#variant.None
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+///
+/// let (send, recv) = channel();
+///
+/// thread::spawn(move || {
+///     send.send(1u8).unwrap();
+///     send.send(2u8).unwrap();
+///     send.send(3u8).unwrap();
+/// });
+///
+/// for x in recv.iter() {
+///     println!("Got: {}", x);
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 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
+/// An iterator that attempts to yield all pending values for a [`Receiver`],
+/// created by [`try_iter`].
+///
+/// [`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`.
+/// This iterator will never block the caller in order to wait for data to
+/// become available. Instead, it will return [`None`].
+///
+/// [`Receiver`]: struct.Receiver.html
+/// [`try_iter`]: struct.Receiver.html#method.try_iter
+/// [`None`]: ../../../std/option/enum.Option.html#variant.None
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let (sender, receiver) = channel();
+///
+/// // Nothing is in the buffer yet
+/// assert!(receiver.try_iter().next().is_none());
+/// println!("Nothing in the buffer...");
+///
+/// thread::spawn(move || {
+///     sender.send(1).unwrap();
+///     sender.send(2).unwrap();
+///     sender.send(3).unwrap();
+/// });
+///
+/// println!("Going to sleep...");
+/// thread::sleep(Duration::from_secs(2)); // block for two seconds
+///
+/// for x in receiver.try_iter() {
+///     println!("Got: {}", x);
+/// }
+/// ```
 #[stable(feature = "receiver_try_iter", since = "1.15.0")]
 #[derive(Debug)]
 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.
+/// An owning iterator over messages on a [`Receiver`],
+/// created by **Receiver::into_iter**.
+///
+/// This iterator will block whenever [`next`]
+/// is called, waiting for a new message, and [`None`] will be
+/// returned if the corresponding channel has hung up.
+///
+/// [`Receiver`]: struct.Receiver.html
+/// [`next`]: ../../../std/iter/trait.Iterator.html#tymethod.next
+/// [`None`]: ../../../std/option/enum.Option.html#variant.None
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+///
+/// let (send, recv) = channel();
+///
+/// thread::spawn(move || {
+///     send.send(1u8).unwrap();
+///     send.send(2u8).unwrap();
+///     send.send(3u8).unwrap();
+/// });
+///
+/// for x in recv.into_iter() {
+///     println!("Got: {}", x);
+/// }
+/// ```
 #[stable(feature = "receiver_into_iter", since = "1.1.0")]
 #[derive(Debug)]
 pub struct IntoIter<T> {
     rx: Receiver<T>
 }
 
-/// The sending-half of Rust's asynchronous channel type. This half can only be
+/// The sending-half of Rust's asynchronous [`channel`] type. This half can only be
 /// owned by one thread, but it can be cloned to send to other threads.
+///
+/// Messages can be sent through this channel with [`send`].
+///
+/// [`channel`]: fn.channel.html
+/// [`send`]: struct.Sender.html#method.send
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::channel;
+/// use std::thread;
+///
+/// let (sender, receiver) = channel();
+/// let sender2 = sender.clone();
+///
+/// // First thread owns sender
+/// thread::spawn(move || {
+///     sender.send(1).unwrap();
+/// });
+///
+/// // Second thread owns sender2
+/// thread::spawn(move || {
+///     sender2.send(2).unwrap();
+/// });
+///
+/// let msg = receiver.recv().unwrap();
+/// let msg2 = receiver.recv().unwrap();
+///
+/// assert_eq!(3, msg + msg2);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Sender<T> {
     inner: UnsafeCell<Flavor<T>>,
@@ -347,8 +498,55 @@ unsafe impl<T: Send> Send for Sender<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for Sender<T> { }
 
-/// The sending-half of Rust's synchronous channel type. This half can only be
-/// owned by one thread, but it can be cloned to send to other threads.
+/// The sending-half of Rust's synchronous [`sync_channel`] type.
+/// This half can only be owned by one thread, but it can be cloned
+/// to send to other threads.
+///
+/// Messages can be sent through this channel with [`send`] or [`try_send`].
+///
+/// [`send`] will block if there is no space in the internal buffer.
+///
+/// [`sync_channel`]: fn.sync_channel.html
+/// [`send`]: struct.SyncSender.html#method.send
+/// [`try_send`]: struct.SyncSender.html#method.try_send
+///
+/// # Examples
+///
+/// ```rust
+/// use std::sync::mpsc::sync_channel;
+/// use std::thread;
+///
+/// // Create a sync_channel with buffer size 2
+/// let (sync_sender, receiver) = sync_channel(2);
+/// let sync_sender2 = sync_sender.clone();
+///
+/// // First thread owns sync_sender
+/// thread::spawn(move || {
+///     sync_sender.send(1).unwrap();
+///     sync_sender.send(2).unwrap();
+/// });
+///
+/// // Second thread owns sync_sender2
+/// thread::spawn(move || {
+///     sync_sender2.send(3).unwrap();
+///     // thread will now block since the buffer is full
+///     println!("Thread unblocked!");
+/// });
+///
+/// let mut msg;
+///
+/// msg = receiver.recv().unwrap();
+/// println!("message {} received", msg);
+///
+/// // "Thread unblocked!" will be printed now
+///
+/// msg = receiver.recv().unwrap();
+/// println!("message {} received", msg);
+///
+/// msg = receiver.recv().unwrap();
+///
+/// println!("message {} received", msg);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct SyncSender<T> {
     inner: Arc<sync::Packet<T>>,
@@ -360,70 +558,97 @@ unsafe impl<T: Send> Send for SyncSender<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> !Sync for SyncSender<T> {}
 
-/// An error returned from the `send` function on channels.
+/// An error returned from the [`Sender::send`] or [`SyncSender::send`]
+/// function on **channel**s.
 ///
-/// A `send` operation can only fail if the receiving end of a channel is
+/// A **send** operation can only fail if the receiving end of a channel is
 /// disconnected, implying that the data could never be received. The error
 /// contains the data being sent as a payload so it can be recovered.
+///
+/// [`Sender::send`]: struct.Sender.html#method.send
+/// [`SyncSender::send`]: struct.SyncSender.html#method.send
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, Clone, Copy)]
 pub struct SendError<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
 
-/// An error returned from the `recv` function on a `Receiver`.
+/// An error returned from the [`recv`] function on a [`Receiver`].
+///
+/// The [`recv`] operation can only fail if the sending half of a
+/// [`channel`][`channel`] (or [`sync_channel`]) is disconnected, implying that no further
+/// messages will ever be received.
 ///
-/// The `recv` operation can only fail if the sending half of a channel is
-/// disconnected, implying that no further messages will ever be received.
+/// [`recv`]: struct.Receiver.html#method.recv
+/// [`Receiver`]: struct.Receiver.html
+/// [`channel`]: fn.channel.html
+/// [`sync_channel`]: fn.sync_channel.html
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct RecvError;
 
-/// This enumeration is the list of the possible reasons that `try_recv` could
-/// not return data when called.
+/// This enumeration is the list of the possible reasons that [`try_recv`] could
+/// not return data when called. This can occur with both a [`channel`] and
+/// a [`sync_channel`].
+///
+/// [`try_recv`]: struct.Receiver.html#method.try_recv
+/// [`channel`]: fn.channel.html
+/// [`sync_channel`]: fn.sync_channel.html
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum TryRecvError {
-    /// This channel is currently empty, but the sender(s) have not yet
+    /// This **channel** is currently empty, but the **Sender**(s) have not yet
     /// disconnected, so data may yet become available.
     #[stable(feature = "rust1", since = "1.0.0")]
     Empty,
 
-    /// This channel's sending half has become disconnected, and there will
-    /// never be any more data received on this channel
+    /// The **channel**'s sending half has become disconnected, and there will
+    /// never be any more data received on it.
     #[stable(feature = "rust1", since = "1.0.0")]
     Disconnected,
 }
 
-/// This enumeration is the list of possible errors that `recv_timeout` could
-/// not return data when called.
+/// This enumeration is the list of possible errors that made [`recv_timeout`]
+/// unable to return data when called. This can occur with both a [`channel`] and
+/// a [`sync_channel`].
+///
+/// [`recv_timeout`]: struct.Receiver.html#method.recv_timeout
+/// [`channel`]: fn.channel.html
+/// [`sync_channel`]: fn.sync_channel.html
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
 #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
 pub enum RecvTimeoutError {
-    /// This channel is currently empty, but the sender(s) have not yet
+    /// This **channel** is currently empty, but the **Sender**(s) have not yet
     /// disconnected, so data may yet become available.
     #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
     Timeout,
-    /// This channel's sending half has become disconnected, and there will
-    /// never be any more data received on this channel
+    /// The **channel**'s sending half has become disconnected, and there will
+    /// never be any more data received on it.
     #[stable(feature = "mpsc_recv_timeout", since = "1.12.0")]
     Disconnected,
 }
 
 /// This enumeration is the list of the possible error outcomes for the
-/// `SyncSender::try_send` method.
+/// [`try_send`] method.
+///
+/// [`try_send`]: struct.SyncSender.html#method.try_send
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(PartialEq, Eq, Clone, Copy)]
 pub enum TrySendError<T> {
-    /// The data could not be sent on the channel because it would require that
+    /// The data could not be sent on the [`sync_channel`] because it would require that
     /// the callee block to send the data.
     ///
     /// If this is a buffered channel, then the buffer is full at this time. If
-    /// this is not a buffered channel, then there is no receiver available to
+    /// this is not a buffered channel, then there is no [`Receiver`] available to
     /// acquire the data.
+    ///
+    /// [`sync_channel`]: fn.sync_channel.html
+    /// [`Receiver`]: struct.Receiver.html
     #[stable(feature = "rust1", since = "1.0.0")]
     Full(#[stable(feature = "rust1", since = "1.0.0")] T),
 
-    /// This channel's receiving half has disconnected, so the data could not be
+    /// This [`sync_channel`]'s receiving half has disconnected, so the data could not be
     /// sent. The data is returned back to the callee in this case.
+    ///
+    /// [`sync_channel`]: fn.sync_channel.html
     #[stable(feature = "rust1", since = "1.0.0")]
     Disconnected(#[stable(feature = "rust1", since = "1.0.0")] T),
 }
@@ -457,15 +682,27 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 }
 
 /// Creates a new asynchronous channel, returning the sender/receiver halves.
-/// All data sent on the sender will become available on the receiver, and no
-/// send will block the calling thread (this channel has an "infinite buffer").
+/// All data sent on the [`Sender`] will become available on the [`Receiver`] in
+/// the same order as it was sent, and no [`send`] will block the calling thread
+/// (this channel has an "infinite buffer", unlike [`sync_channel`], which will
+/// block after its buffer limit is reached). [`recv`] will block until a message
+/// is available.
 ///
-/// If the [`Receiver`] is disconnected while trying to [`send()`] with the
-/// [`Sender`], the [`send()`] method will return an error.
+/// The [`Sender`] can be cloned to [`send`] to the same channel multiple times, but
+/// only one [`Receiver`] is supported.
 ///
-/// [`send()`]: ../../../std/sync/mpsc/struct.Sender.html#method.send
-/// [`Sender`]: ../../../std/sync/mpsc/struct.Sender.html
-/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
+/// If the [`Receiver`] is disconnected while trying to [`send`] with the
+/// [`Sender`], the [`send`] method will return a [`SendError`]. Similarly, If the
+/// [`Sender`] is disconnected while trying to [`recv`], the [`recv`] method will
+/// return a [`RecvError`].
+///
+/// [`send`]: struct.Sender.html#method.send
+/// [`recv`]: struct.Receiver.html#method.recv
+/// [`Sender`]: struct.Sender.html
+/// [`Receiver`]: struct.Receiver.html
+/// [`sync_channel`]: fn.sync_channel.html
+/// [`SendError`]: struct.SendError.html
+/// [`RecvError`]: struct.RecvError.html
 ///
 /// # Examples
 ///
@@ -473,20 +710,18 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
 /// use std::sync::mpsc::channel;
 /// use std::thread;
 ///
-/// // tx is the sending half (tx for transmission), and rx is the receiving
-/// // half (rx for receiving).
-/// let (tx, rx) = channel();
+/// let (sender, receiver) = channel();
 ///
 /// // Spawn off an expensive computation
 /// thread::spawn(move|| {
 /// #   fn expensive_computation() {}
-///     tx.send(expensive_computation()).unwrap();
+///     sender.send(expensive_computation()).unwrap();
 /// });
 ///
 /// // Do some useful work for awhile
 ///
 /// // Let's see what that answer was
-/// println!("{:?}", rx.recv().unwrap());
+/// println!("{:?}", receiver.recv().unwrap());
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
@@ -495,24 +730,32 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
 }
 
 /// Creates a new synchronous, bounded channel.
-///
-/// Like asynchronous channels, the [`Receiver`] will block until a message
-/// becomes available. These channels differ greatly in the semantics of the
-/// sender from asynchronous channels, however.
+/// All data sent on the [`SyncSender`] will become available on the [`Receiver`]
+/// in the same order as it was sent. Like asynchronous [`channel`]s, the
+/// [`Receiver`] will block until a message becomes available. `sync_channel`
+/// differs greatly in the semantics of the sender, however.
 ///
 /// This channel has an internal buffer on which messages will be queued.
 /// `bound` specifies the buffer size. When the internal buffer becomes full,
 /// future sends will *block* waiting for the buffer to open up. Note that a
 /// buffer size of 0 is valid, in which case this becomes "rendezvous channel"
-/// where each [`send()`] will not return until a recv is paired with it.
+/// where each [`send`] will not return until a [`recv`] is paired with it.
+///
+/// The [`SyncSender`] can be cloned to [`send`] to the same channel multiple
+/// times, but only one [`Receiver`] is supported.
 ///
-/// Like asynchronous channels, if the [`Receiver`] is disconnected while
-/// trying to [`send()`] with the [`SyncSender`], the [`send()`] method will
-/// return an error.
+/// Like asynchronous channels, if the [`Receiver`] is disconnected while trying
+/// to [`send`] with the [`SyncSender`], the [`send`] method will return a
+/// [`SendError`]. Similarly, If the [`SyncSender`] is disconnected while trying
+/// to [`recv`], the [`recv`] method will return a [`RecvError`].
 ///
-/// [`send()`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
-/// [`SyncSender`]: ../../../std/sync/mpsc/struct.SyncSender.html
-/// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
+/// [`channel`]: fn.channel.html
+/// [`send`]: struct.SyncSender.html#method.send
+/// [`recv`]: struct.Receiver.html#method.recv
+/// [`SyncSender`]: struct.SyncSender.html
+/// [`Receiver`]: struct.Receiver.html
+/// [`SendError`]: struct.SendError.html
+/// [`RecvError`]: struct.RecvError.html
 ///
 /// # Examples
 ///
@@ -520,18 +763,18 @@ pub fn channel<T>() -> (Sender<T>, Receiver<T>) {
 /// use std::sync::mpsc::sync_channel;
 /// use std::thread;
 ///
-/// let (tx, rx) = sync_channel(1);
+/// let (sender, receiver) = sync_channel(1);
 ///
 /// // this returns immediately
-/// tx.send(1).unwrap();
+/// sender.send(1).unwrap();
 ///
 /// thread::spawn(move|| {
 ///     // this will block until the previous message has been received
-///     tx.send(2).unwrap();
+///     sender.send(2).unwrap();
 /// });
 ///
-/// assert_eq!(rx.recv().unwrap(), 1);
-/// assert_eq!(rx.recv().unwrap(), 2);
+/// assert_eq!(receiver.recv().unwrap(), 1);
+/// assert_eq!(receiver.recv().unwrap(), 2);
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>) {
@@ -556,10 +799,13 @@ impl<T> Sender<T> {
     /// A successful send occurs when it is determined that the other end of
     /// the channel has not hung up already. An unsuccessful send would be one
     /// where the corresponding receiver has already been deallocated. Note
-    /// that a return value of `Err` means that the data will never be
-    /// received, but a return value of `Ok` does *not* mean that the data
+    /// that a return value of [`Err`] means that the data will never be
+    /// received, but a return value of [`Ok`] does *not* mean that the data
     /// will be received.  It is possible for the corresponding receiver to
-    /// hang up immediately after this function returns `Ok`.
+    /// hang up immediately after this function returns [`Ok`].
+    ///
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    /// [`Ok`]: ../../../std/result/enum.Result.html#variant.Ok
     ///
     /// This method will never block the current thread.
     ///
@@ -675,7 +921,7 @@ impl<T> Drop for Sender<T> {
     }
 }
 
-#[stable(feature = "mpsc_debug", since = "1.7.0")]
+#[stable(feature = "mpsc_debug", since = "1.8.0")]
 impl<T> fmt::Debug for Sender<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "Sender {{ .. }}")
@@ -699,12 +945,37 @@ impl<T> SyncSender<T> {
     /// Note that a successful send does *not* guarantee that the receiver will
     /// ever see the data if there is a buffer on this channel. Items may be
     /// enqueued in the internal buffer for the receiver to receive at a later
-    /// time. If the buffer size is 0, however, it can be guaranteed that the
-    /// receiver has indeed received the data if this function returns success.
+    /// time. If the buffer size is 0, however, the channel becomes a rendezvous
+    /// channel and it guarantees that the receiver has indeed received
+    /// the data if this function returns success.
     ///
-    /// This function will never panic, but it may return `Err` if the
-    /// `Receiver` has disconnected and is no longer able to receive
+    /// This function will never panic, but it may return [`Err`] if the
+    /// [`Receiver`] has disconnected and is no longer able to receive
     /// information.
+    ///
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    /// [`Receiver`]: ../../../std/sync/mpsc/struct.Receiver.html
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::sync_channel;
+    /// use std::thread;
+    ///
+    /// // Create a rendezvous sync_channel with buffer size 0
+    /// let (sync_sender, receiver) = sync_channel(0);
+    ///
+    /// thread::spawn(move || {
+    ///    println!("sending message...");
+    ///    sync_sender.send(1).unwrap();
+    ///    // Thread is now blocked until the message is received
+    ///
+    ///    println!("...message received!");
+    /// });
+    ///
+    /// let msg = receiver.recv().unwrap();
+    /// assert_eq!(1, msg);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         self.inner.send(t).map_err(SendError)
@@ -712,13 +983,53 @@ impl<T> SyncSender<T> {
 
     /// Attempts to send a value on this channel without blocking.
     ///
-    /// This method differs from `send` by returning immediately if the
+    /// This method differs from [`send`] by returning immediately if the
     /// channel's buffer is full or no receiver is waiting to acquire some
-    /// data. Compared with `send`, this function has two failure cases
+    /// data. Compared with [`send`], this function has two failure cases
     /// instead of one (one for disconnection, one for a full buffer).
     ///
-    /// See `SyncSender::send` for notes about guarantees of whether the
+    /// See [`send`] for notes about guarantees of whether the
     /// receiver has received the data or not if this function is successful.
+    ///
+    /// [`send`]: ../../../std/sync/mpsc/struct.SyncSender.html#method.send
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::sync_channel;
+    /// use std::thread;
+    ///
+    /// // Create a sync_channel with buffer size 1
+    /// let (sync_sender, receiver) = sync_channel(1);
+    /// let sync_sender2 = sync_sender.clone();
+    ///
+    /// // First thread owns sync_sender
+    /// thread::spawn(move || {
+    ///     sync_sender.send(1).unwrap();
+    ///     sync_sender.send(2).unwrap();
+    ///     // Thread blocked
+    /// });
+    ///
+    /// // Second thread owns sync_sender2
+    /// thread::spawn(move || {
+    ///     // This will return an error and send
+    ///     // no message if the buffer is full
+    ///     sync_sender2.try_send(3).is_err();
+    /// });
+    ///
+    /// let mut msg;
+    /// msg = receiver.recv().unwrap();
+    /// println!("message {} received", msg);
+    ///
+    /// msg = receiver.recv().unwrap();
+    /// println!("message {} received", msg);
+    ///
+    /// // Third message may have never been sent
+    /// match receiver.try_recv() {
+    ///     Ok(msg) => println!("message {} received", msg),
+    ///     Err(_) => println!("the third message was never sent"),
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> {
         self.inner.try_send(t)
@@ -740,7 +1051,7 @@ impl<T> Drop for SyncSender<T> {
     }
 }
 
-#[stable(feature = "mpsc_debug", since = "1.7.0")]
+#[stable(feature = "mpsc_debug", since = "1.8.0")]
 impl<T> fmt::Debug for SyncSender<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "SyncSender {{ .. }}")
@@ -756,7 +1067,7 @@ impl<T> Receiver<T> {
         Receiver { inner: UnsafeCell::new(inner) }
     }
 
-    /// Attempts to return a pending value on this receiver without blocking
+    /// Attempts to return a pending value on this receiver without blocking.
     ///
     /// This method will never block the caller in order to wait for data to
     /// become available. Instead, this will always return immediately with a
@@ -764,6 +1075,21 @@ impl<T> Receiver<T> {
     ///
     /// This is useful for a flavor of "optimistic check" before deciding to
     /// block on a receiver.
+    ///
+    /// Compared with [`recv`], this function has two failure cases instead of one
+    /// (one for disconnection, one for an empty buffer).
+    ///
+    /// [`recv`]: struct.Receiver.html#method.recv
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::{Receiver, channel};
+    ///
+    /// let (_, receiver): (_, Receiver<i32>) = channel();
+    ///
+    /// assert!(receiver.try_recv().is_err());
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_recv(&self) -> Result<T, TryRecvError> {
         loop {
@@ -819,15 +1145,19 @@ impl<T> Receiver<T> {
     ///
     /// 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.
+    /// sent to the corresponding [`Sender`][] (or [`SyncSender`]), 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
+    /// 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.
     ///
+    /// [`Sender`]: struct.Sender.html
+    /// [`SyncSender`]: struct.SyncSender.html
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    ///
     /// # Examples
     ///
     /// ```
@@ -907,15 +1237,19 @@ impl<T> Receiver<T> {
     ///
     /// 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.
+    /// sent to the corresponding [`Sender`][] (or [`SyncSender`]), 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
+    /// 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.
     ///
+    /// [`Sender`]: struct.Sender.html
+    /// [`SyncSender`]: struct.SyncSender.html
+    /// [`Err`]: ../../../std/result/enum.Result.html#variant.Err
+    ///
     /// # Examples
     ///
     /// ```no_run
@@ -993,7 +1327,29 @@ impl<T> Receiver<T> {
     }
 
     /// Returns an iterator that will block waiting for messages, but never
-    /// `panic!`. It will return `None` when the channel has hung up.
+    /// [`panic!`]. It will return [`None`] when the channel has hung up.
+    ///
+    /// [`panic!`]: ../../../std/macro.panic.html
+    /// [`None`]: ../../../std/option/enum.Option.html#variant.None
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::channel;
+    /// use std::thread;
+    ///
+    /// let (send, recv) = channel();
+    ///
+    /// thread::spawn(move || {
+    ///     send.send(1u8).unwrap();
+    ///     send.send(2u8).unwrap();
+    ///     send.send(3u8).unwrap();
+    /// });
+    ///
+    /// for x in recv.iter() {
+    ///     println!("Got: {}", x);
+    /// }
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn iter(&self) -> Iter<T> {
         Iter { rx: self }
@@ -1001,8 +1357,37 @@ impl<T> Receiver<T> {
 
     /// 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
+    /// channel has hung up. The iterator will never [`panic!`] or block the
     /// user by waiting for values.
+    ///
+    /// [`panic!`]: ../../../std/macro.panic.html
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::sync::mpsc::channel;
+    /// use std::thread;
+    /// use std::time::Duration;
+    ///
+    /// let (sender, receiver) = channel();
+    ///
+    /// // Nothing is in the buffer yet
+    /// assert!(receiver.try_iter().next().is_none());
+    /// println!("Nothing in the buffer...");
+    ///
+    /// thread::spawn(move || {
+    ///     sender.send(1).unwrap();
+    ///     sender.send(2).unwrap();
+    ///     sender.send(3).unwrap();
+    /// });
+    ///
+    /// println!("Going to sleep...");
+    /// thread::sleep(Duration::from_secs(2)); // block for two seconds
+    ///
+    /// for x in receiver.try_iter() {
+    ///     println!("Got: {}", x);
+    /// }
+    /// ```
     #[stable(feature = "receiver_try_iter", since = "1.15.0")]
     pub fn try_iter(&self) -> TryIter<T> {
         TryIter { rx: self }
@@ -1132,7 +1517,7 @@ impl<T> Drop for Receiver<T> {
     }
 }
 
-#[stable(feature = "mpsc_debug", since = "1.7.0")]
+#[stable(feature = "mpsc_debug", since = "1.8.0")]
 impl<T> fmt::Debug for Receiver<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "Receiver {{ .. }}")
@@ -1259,7 +1644,7 @@ impl error::Error for TryRecvError {
     }
 }
 
-#[stable(feature = "mpsc_recv_timeout_error", since = "1.14.0")]
+#[stable(feature = "mpsc_recv_timeout_error", since = "1.15.0")]
 impl fmt::Display for RecvTimeoutError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -1273,7 +1658,7 @@ impl fmt::Display for RecvTimeoutError {
     }
 }
 
-#[stable(feature = "mpsc_recv_timeout_error", since = "1.14.0")]
+#[stable(feature = "mpsc_recv_timeout_error", since = "1.15.0")]
 impl error::Error for RecvTimeoutError {
     fn description(&self) -> &str {
         match *self {
diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index 8d80f942ff7..296773d20f6 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -1,29 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A mostly lock-free multi-producer, single consumer queue.
 //!
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index 5858e4b6ddb..1148bc66fba 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -1,31 +1,12 @@
-/* Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice,
- *       this list of conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are
- * those of the authors and should not be interpreted as representing official
- * policies, either expressed or implied, of Dmitry Vyukov.
- */
-
-// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A single-producer single-consumer concurrent queue
 //!
@@ -33,6 +14,8 @@
 //! concurrently between two threads. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
+// http://www.1024cores.net/home/lock-free-algorithms/queues/unbounded-spsc-queue
+
 use alloc::boxed::Box;
 use core::ptr;
 use core::cell::UnsafeCell;
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index 97b84d59218..9a242a96d46 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -10,7 +10,6 @@
 
 use cell::UnsafeCell;
 use fmt;
-use marker;
 use mem;
 use ops::{Deref, DerefMut};
 use ptr;
@@ -30,7 +29,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 ///
 /// The mutexes in this module implement a strategy called "poisoning" where a
 /// mutex is considered poisoned whenever a thread panics while holding the
-/// lock. Once a mutex is poisoned, all other threads are unable to access the
+/// mutex. Once a mutex is poisoned, all other threads are unable to access the
 /// data by default as it is likely tainted (some invariant is not being
 /// upheld).
 ///
@@ -61,7 +60,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 /// let data = Arc::new(Mutex::new(0));
 ///
 /// let (tx, rx) = channel();
-/// for _ in 0..10 {
+/// for _ in 0..N {
 ///     let (data, tx) = (data.clone(), tx.clone());
 ///     thread::spawn(move || {
 ///         // The shared state can only be accessed once the lock is held.
@@ -115,7 +114,7 @@ pub struct Mutex<T: ?Sized> {
     // 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
+    // ensure that the native mutex is used correctly we box the inner mutex to
     // give it a constant address.
     inner: Box<sys::Mutex>,
     poison: poison::Flag,
@@ -132,16 +131,16 @@ unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
 ///
-/// The data protected by the mutex can be access through this guard via its
+/// The data protected by the mutex can be accessed through this guard via its
 /// [`Deref`] and [`DerefMut`] implementations.
 ///
-/// This structure is created by the [`lock()`] and [`try_lock()`] methods on
+/// This structure is created by the [`lock`] and [`try_lock`] methods on
 /// [`Mutex`].
 ///
 /// [`Deref`]: ../../std/ops/trait.Deref.html
 /// [`DerefMut`]: ../../std/ops/trait.DerefMut.html
-/// [`lock()`]: struct.Mutex.html#method.lock
-/// [`try_lock()`]: struct.Mutex.html#method.try_lock
+/// [`lock`]: struct.Mutex.html#method.lock
+/// [`try_lock`]: struct.Mutex.html#method.try_lock
 /// [`Mutex`]: struct.Mutex.html
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -153,7 +152,9 @@ pub struct MutexGuard<'a, T: ?Sized + 'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
+impl<'a, T: ?Sized> !Send for MutexGuard<'a, T> { }
+#[stable(feature = "mutexguard", since = "1.19.0")]
+unsafe impl<'a, T: ?Sized + Sync> Sync for MutexGuard<'a, T> { }
 
 impl<T> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
@@ -183,7 +184,7 @@ impl<T: ?Sized> Mutex<T> {
     /// Acquires a mutex, blocking the current thread until it is able to do so.
     ///
     /// This function will block the local thread until it is available to acquire
-    /// the mutex. Upon returning, the thread is the only thread with the mutex
+    /// the mutex. Upon returning, the thread is the only thread with the lock
     /// held. An RAII guard is returned to allow scoped unlock of the lock. When
     /// the guard goes out of scope, the mutex will be unlocked.
     ///
@@ -267,9 +268,9 @@ impl<T: ?Sized> Mutex<T> {
         }
     }
 
-    /// Determines whether the lock is poisoned.
+    /// Determines whether the mutex is poisoned.
     ///
-    /// If another thread is active, the lock can still become poisoned at any
+    /// If another thread is active, the mutex can still become poisoned at any
     /// time. You should not trust a `false` value for program correctness
     /// without additional synchronization.
     ///
@@ -312,7 +313,7 @@ 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 lock.
+        // `self` so there's no need to lock the inner mutex.
         //
         // 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
@@ -353,7 +354,7 @@ 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 lock.
+        // there's no need to lock the inner mutex.
         let data = unsafe { &mut *self.data.get() };
         poison::map_result(self.poison.borrow(), |_| data )
     }
@@ -371,7 +372,7 @@ unsafe impl<#[may_dangle] T: ?Sized> Drop for Mutex<T> {
     }
 }
 
-#[stable(feature = "mutex_default", since = "1.9.0")]
+#[stable(feature = "mutex_default", since = "1.10.0")]
 impl<T: ?Sized + Default> Default for Mutex<T> {
     /// Creates a `Mutex<T>`, with the `Default` value for T.
     fn default() -> Mutex<T> {
@@ -459,9 +460,6 @@ mod tests {
     #[derive(Eq, PartialEq, Debug)]
     struct NonCopy(i32);
 
-    unsafe impl<T: Send> Send for Packet<T> {}
-    unsafe impl<T> Sync for Packet<T> {}
-
     #[test]
     fn smoke() {
         let m = Mutex::new(());
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 1e7394c0b09..d9edf5d1254 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -72,9 +72,11 @@ use thread::{self, Thread};
 
 /// A synchronization primitive which can be used to run a one-time global
 /// initialization. Useful for one-time initialization for FFI or related
-/// functionality. This type can only be constructed with the `ONCE_INIT`
+/// functionality. This type can only be constructed with the [`ONCE_INIT`]
 /// value.
 ///
+/// [`ONCE_INIT`]: constant.ONCE_INIT.html
+///
 /// # Examples
 ///
 /// ```
@@ -101,15 +103,28 @@ unsafe impl Sync for Once {}
 #[stable(feature = "rust1", since = "1.0.0")]
 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.
+/// State yielded to the [`call_once_force`] method which can be used to query
+/// whether the [`Once`] was previously poisoned or not.
+///
+/// [`call_once_force`]: struct.Once.html#method.call_once_force
+/// [`Once`]: struct.Once.html
 #[unstable(feature = "once_poison", issue = "33577")]
 #[derive(Debug)]
 pub struct OnceState {
     poisoned: bool,
 }
 
-/// Initialization value for static `Once` values.
+/// Initialization value for static [`Once`] values.
+///
+/// [`Once`]: struct.Once.html
+///
+/// # Examples
+///
+/// ```
+/// use std::sync::{Once, ONCE_INIT};
+///
+/// static START: Once = ONCE_INIT;
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub const ONCE_INIT: Once = Once::new();
 
@@ -212,15 +227,19 @@ impl Once {
         self.call_inner(false, &mut |_| f.take().unwrap()());
     }
 
-    /// Performs the same function as `call_once` except ignores poisoning.
+    /// Performs the same function as [`call_once`] except ignores poisoning.
+    ///
+    /// [`call_once`]: struct.Once.html#method.call_once
     ///
     /// If this `Once` has been poisoned (some initialization panicked) then
     /// this function will continue to attempt to call initialization functions
     /// until one of them doesn't panic.
     ///
-    /// The closure `f` is yielded a structure which can be used to query the
+    /// The closure `f` is yielded a [`OnceState`] structure which can be used to query the
     /// state of this `Once` (whether initialization has previously panicked or
     /// not).
+    ///
+    /// [`OnceState`]: struct.OnceState.html
     #[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`.
@@ -366,10 +385,12 @@ impl Drop for Finish {
 }
 
 impl OnceState {
-    /// Returns whether the associated `Once` has been poisoned.
+    /// Returns whether the associated [`Once`] has been poisoned.
     ///
-    /// Once an initalization routine for a `Once` has panicked it will forever
+    /// Once an initalization routine for a [`Once`] has panicked it will forever
     /// indicate to future forced initialization routines that it is poisoned.
+    ///
+    /// [`Once`]: struct.Once.html
     #[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 a3db0adeda0..95bc8d30932 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -78,11 +78,11 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 ///
-/// This structure is created by the [`read()`] and [`try_read()`] methods on
+/// This structure is created by the [`read`] and [`try_read`] methods on
 /// [`RwLock`].
 ///
-/// [`read()`]: struct.RwLock.html#method.read
-/// [`try_read()`]: struct.RwLock.html#method.try_read
+/// [`read`]: struct.RwLock.html#method.read
+/// [`try_read`]: struct.RwLock.html#method.try_read
 /// [`RwLock`]: struct.RwLock.html
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -96,11 +96,11 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
 /// RAII structure used to release the exclusive write access of a lock when
 /// dropped.
 ///
-/// This structure is created by the [`write()`] and [`try_write()`] methods
+/// This structure is created by the [`write`] and [`try_write`] methods
 /// on [`RwLock`].
 ///
-/// [`write()`]: struct.RwLock.html#method.write
-/// [`try_write()`]: struct.RwLock.html#method.try_write
+/// [`write`]: struct.RwLock.html#method.write
+/// [`try_write`]: struct.RwLock.html#method.try_write
 /// [`RwLock`]: struct.RwLock.html
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -330,7 +330,7 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
     }
 }
 
-#[stable(feature = "rw_lock_default", since = "1.9.0")]
+#[stable(feature = "rw_lock_default", since = "1.10.0")]
 impl<T: Default> Default for RwLock<T> {
     /// Creates a new `RwLock<T>`, with the `Default` value for T.
     fn default() -> RwLock<T> {
diff --git a/src/libstd/sys/redox/fast_thread_local.rs b/src/libstd/sys/redox/fast_thread_local.rs
index 6eeae2d90ea..7dc61ce6654 100644
--- a/src/libstd/sys/redox/fast_thread_local.rs
+++ b/src/libstd/sys/redox/fast_thread_local.rs
@@ -12,9 +12,10 @@
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
 use cell::{Cell, UnsafeCell};
-use intrinsics;
+use mem;
 use ptr;
 
+
 pub struct Key<T> {
     inner: UnsafeCell<Option<T>>,
 
@@ -37,7 +38,7 @@ impl<T> Key<T> {
 
     pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
         unsafe {
-            if intrinsics::needs_drop::<T>() && self.dtor_running.get() {
+            if mem::needs_drop::<T>() && self.dtor_running.get() {
                 return None
             }
             self.register_dtor();
@@ -46,7 +47,7 @@ impl<T> Key<T> {
     }
 
     unsafe fn register_dtor(&self) {
-        if !intrinsics::needs_drop::<T>() || self.dtor_registered.get() {
+        if !mem::needs_drop::<T>() || self.dtor_registered.get() {
             return
         }
 
@@ -96,17 +97,17 @@ pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
     // `None`.
     (*ptr).dtor_running.set(true);
 
-    // The OSX implementation of TLS apparently had an odd aspect to it
+    // The macOS implementation of TLS apparently had an odd aspect to it
     // where the pointer we have may be overwritten while this destructor
     // is running. Specifically if a TLS destructor re-accesses TLS it may
     // trigger a re-initialization of all TLS variables, paving over at
     // least some destroyed ones with initial values.
     //
-    // This means that if we drop a TLS value in place on OSX that we could
+    // This means that if we drop a TLS value in place on macOS that we could
     // revert the value to its original state halfway through the
     // destructor, which would be bad!
     //
-    // Hence, we use `ptr::read` on OSX (to move to a "safe" location)
+    // Hence, we use `ptr::read` on macOS (to move to a "safe" location)
     // instead of drop_in_place.
     if cfg!(target_os = "macos") {
         ptr::read((*ptr).inner.get());
diff --git a/src/libstd/sys/redox/os_str.rs b/src/libstd/sys/redox/os_str.rs
index 474d59eed83..c2bba07f68c 100644
--- a/src/libstd/sys/redox/os_str.rs
+++ b/src/libstd/sys/redox/os_str.rs
@@ -104,6 +104,12 @@ impl Buf {
     pub fn into_box(self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_boxed_slice()) }
     }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Buf { inner: inner.into_vec() }
+    }
 }
 
 impl Slice {
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index 60dc03fcf47..95e9438cd71 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -249,7 +249,7 @@ impl Command {
     // mutex, and then after the fork they unlock it.
     //
     // Despite this information, libnative's spawn has been witnessed to
-    // deadlock on both OSX and FreeBSD. I'm not entirely sure why, but
+    // deadlock on both macOS and FreeBSD. I'm not entirely sure why, but
     // all collected backtraces point at malloc/free traffic in the
     // child spawned process.
     //
@@ -270,19 +270,22 @@ impl Command {
         }
 
         if let Some(fd) = stdio.stderr.fd() {
-            let _ = syscall::close(2);
-            t!(cvt(syscall::dup(fd, &[])));
-            let _ = syscall::close(fd);
+            t!(cvt(syscall::dup2(fd, 2, &[])));
+            let mut flags = t!(cvt(syscall::fcntl(2, syscall::F_GETFL, 0)));
+            flags &= ! syscall::O_CLOEXEC;
+            t!(cvt(syscall::fcntl(2, syscall::F_SETFL, flags)));
         }
         if let Some(fd) = stdio.stdout.fd() {
-            let _ = syscall::close(1);
-            t!(cvt(syscall::dup(fd, &[])));
-            let _ = syscall::close(fd);
+            t!(cvt(syscall::dup2(fd, 1, &[])));
+            let mut flags = t!(cvt(syscall::fcntl(1, syscall::F_GETFL, 0)));
+            flags &= ! syscall::O_CLOEXEC;
+            t!(cvt(syscall::fcntl(1, syscall::F_SETFL, flags)));
         }
         if let Some(fd) = stdio.stdin.fd() {
-            let _ = syscall::close(0);
-            t!(cvt(syscall::dup(fd, &[])));
-            let _ = syscall::close(fd);
+            t!(cvt(syscall::dup2(fd, 0, &[])));
+            let mut flags = t!(cvt(syscall::fcntl(0, syscall::F_GETFL, 0)));
+            flags &= ! syscall::O_CLOEXEC;
+            t!(cvt(syscall::fcntl(0, syscall::F_SETFL, flags)));
         }
 
         if let Some(g) = self.gid {
diff --git a/src/libstd/sys/redox/syscall/call.rs b/src/libstd/sys/redox/syscall/call.rs
index f58c240f31e..fadf7325d75 100644
--- a/src/libstd/sys/redox/syscall/call.rs
+++ b/src/libstd/sys/redox/syscall/call.rs
@@ -71,6 +71,11 @@ pub fn dup(fd: usize, buf: &[u8]) -> Result<usize> {
     unsafe { syscall3(SYS_DUP, fd, buf.as_ptr() as usize, buf.len()) }
 }
 
+/// Copy and transform a file descriptor
+pub fn dup2(fd: usize, newfd: usize, buf: &[u8]) -> Result<usize> {
+    unsafe { syscall4(SYS_DUP2, fd, newfd, buf.as_ptr() as usize, buf.len()) }
+}
+
 /// Replace the current process with a new executable
 pub fn execve(path: &str, args: &[[usize; 2]]) -> Result<usize> {
     unsafe { syscall4(SYS_EXECVE, path.as_ptr() as usize, path.len(),
diff --git a/src/libstd/sys/redox/syscall/number.rs b/src/libstd/sys/redox/syscall/number.rs
index 358746cd20a..98f8b73e4e1 100644
--- a/src/libstd/sys/redox/syscall/number.rs
+++ b/src/libstd/sys/redox/syscall/number.rs
@@ -28,6 +28,7 @@ pub const SYS_UNLINK: usize =   SYS_CLASS_PATH | 10;
 
 pub const SYS_CLOSE: usize =    SYS_CLASS_FILE | 6;
 pub const SYS_DUP: usize =      SYS_CLASS_FILE | SYS_RET_FILE | 41;
+pub const SYS_DUP2: usize =     SYS_CLASS_FILE | SYS_RET_FILE | 63;
 pub const SYS_READ: usize =     SYS_CLASS_FILE | SYS_ARG_MSLICE | 3;
 pub const SYS_WRITE: usize =    SYS_CLASS_FILE | SYS_ARG_SLICE | 4;
 pub const SYS_LSEEK: usize =    SYS_CLASS_FILE | 19;
diff --git a/src/libstd/sys/redox/thread_local.rs b/src/libstd/sys/redox/thread_local.rs
index abdd9ace795..cacd84e2102 100644
--- a/src/libstd/sys/redox/thread_local.rs
+++ b/src/libstd/sys/redox/thread_local.rs
@@ -64,3 +64,8 @@ pub unsafe fn set(key: Key, value: *mut u8) {
 pub unsafe fn destroy(key: Key) {
     keys().remove(&key);
 }
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}
diff --git a/src/libstd/sys/unix/backtrace/mod.rs b/src/libstd/sys/unix/backtrace/mod.rs
index 29d4012dcdf..bf52da2ed4a 100644
--- a/src/libstd/sys/unix/backtrace/mod.rs
+++ b/src/libstd/sys/unix/backtrace/mod.rs
@@ -13,7 +13,7 @@
 /// Some methods of getting a backtrace:
 ///
 /// * The backtrace() functions on unix. It turns out this doesn't work very
-///   well for green threads on OSX, and the address to symbol portion of it
+///   well for green threads on macOS, and the address to symbol portion of it
 ///   suffers problems that are described below.
 ///
 /// * Using libunwind. This is more difficult than it sounds because libunwind
@@ -51,9 +51,9 @@
 ///
 /// * Use dladdr(). The original backtrace()-based idea actually uses dladdr()
 ///   behind the scenes to translate, and this is why backtrace() was not used.
-///   Conveniently, this method works fantastically on OSX. It appears dladdr()
+///   Conveniently, this method works fantastically on macOS. It appears dladdr()
 ///   uses magic to consult the local symbol table, or we're putting everything
-///   in the dynamic symbol table anyway. Regardless, for OSX, this is the
+///   in the dynamic symbol table anyway. Regardless, for macOS, this is the
 ///   method used for translation. It's provided by the system and easy to do.o
 ///
 ///   Sadly, all other systems have a dladdr() implementation that does not
@@ -75,7 +75,7 @@
 /// * Use `libbacktrace`. It turns out that this is a small library bundled in
 ///   the gcc repository which provides backtrace and symbol translation
 ///   functionality. All we really need from it is the backtrace functionality,
-///   and we only really need this on everything that's not OSX, so this is the
+///   and we only really need this on everything that's not macOS, so this is the
 ///   chosen route for now.
 ///
 /// In summary, the current situation uses libgcc_s to get a trace of stack
diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs
index 1ba4a104e51..d688f2fa504 100644
--- a/src/libstd/sys/unix/ext/net.rs
+++ b/src/libstd/sys/unix/ext/net.rs
@@ -204,7 +204,7 @@ impl SocketAddr {
         let len = self.len as usize - sun_path_offset();
         let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) };
 
-        // OSX seems to return a len of 16 and a zeroed sun_path for unnamed addresses
+        // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses
         if len == 0 || (cfg!(not(target_os = "linux")) && self.addr.sun_path[0] == 0) {
             AddressKind::Unnamed
         } else if self.addr.sun_path[0] == 0 {
@@ -375,12 +375,12 @@ impl UnixStream {
 
     /// Sets the read timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`read()`] calls will block
+    /// If the provided value is [`None`], then [`read`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../../../std/io/trait.Read.html#tymethod.read
+    /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
@@ -399,12 +399,12 @@ impl UnixStream {
 
     /// Sets the write timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`write()`] calls will block
+    /// If the provided value is [`None`], then [`write`] calls will block
     /// indefinitely. It is an error to pass the zero [`Duration`] to this
     /// method.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`read()`]: ../../../../std/io/trait.Write.html#tymethod.write
+    /// [`read`]: ../../../../std/io/trait.Write.html#tymethod.write
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
@@ -641,7 +641,7 @@ impl UnixListener {
                 let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?;
                 let (addr, len) = sockaddr_un(path)?;
 
-                cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len))?;
+                cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?;
                 cvt(libc::listen(*inner.as_inner(), 128))?;
 
                 Ok(UnixListener(inner))
@@ -920,7 +920,7 @@ impl UnixDatagram {
                 let socket = UnixDatagram::unbound()?;
                 let (addr, len) = sockaddr_un(path)?;
 
-                cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len))?;
+                cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?;
 
                 Ok(socket)
             }
@@ -974,12 +974,12 @@ impl UnixDatagram {
 
     /// Connects the socket to the specified address.
     ///
-    /// The [`send()`] method may be used to send data to the specified address.
-    /// [`recv()`] and [`recv_from()`] will only receive data from that address.
+    /// The [`send`] method may be used to send data to the specified address.
+    /// [`recv`] and [`recv_from`] will only receive data from that address.
     ///
-    /// [`send()`]: #method.send
-    /// [`recv()`]: #method.recv
-    /// [`recv_from()`]: #method.recv_from
+    /// [`send`]: #method.send
+    /// [`recv`]: #method.recv
+    /// [`recv_from`]: #method.recv_from
     ///
     /// # Examples
     ///
@@ -1047,9 +1047,9 @@ impl UnixDatagram {
 
     /// Returns the address of this socket's peer.
     ///
-    /// The [`connect()`] method will connect the socket to a peer.
+    /// The [`connect`] method will connect the socket to a peer.
     ///
-    /// [`connect()`]: #method.connect
+    /// [`connect`]: #method.connect
     ///
     /// # Examples
     ///
@@ -1178,13 +1178,13 @@ impl UnixDatagram {
 
     /// Sets the read timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`recv()`] and [`recv_from()`] calls will
+    /// 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.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`recv()`]: #method.recv
-    /// [`recv_from()`]: #method.recv_from
+    /// [`recv`]: #method.recv
+    /// [`recv_from`]: #method.recv_from
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
@@ -1203,13 +1203,13 @@ impl UnixDatagram {
 
     /// Sets the write timeout for the socket.
     ///
-    /// If the provided value is [`None`], then [`send()`] and [`send_to()`] calls will
+    /// 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.
     ///
     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
-    /// [`send()`]: #method.send
-    /// [`send_to()`]: #method.send_to
+    /// [`send`]: #method.send
+    /// [`send_to`]: #method.send_to
     /// [`Duration`]: ../../../../std/time/struct.Duration.html
     ///
     /// # Examples
diff --git a/src/libstd/sys/unix/fast_thread_local.rs b/src/libstd/sys/unix/fast_thread_local.rs
index f4f73646e1b..6b3973de84c 100644
--- a/src/libstd/sys/unix/fast_thread_local.rs
+++ b/src/libstd/sys/unix/fast_thread_local.rs
@@ -13,7 +13,7 @@
 
 use cell::{Cell, UnsafeCell};
 use fmt;
-use intrinsics;
+use mem;
 use ptr;
 
 pub struct Key<T> {
@@ -44,7 +44,7 @@ impl<T> Key<T> {
 
     pub fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
         unsafe {
-            if intrinsics::needs_drop::<T>() && self.dtor_running.get() {
+            if mem::needs_drop::<T>() && self.dtor_running.get() {
                 return None
             }
             self.register_dtor();
@@ -53,7 +53,7 @@ impl<T> Key<T> {
     }
 
     unsafe fn register_dtor(&self) {
-        if !intrinsics::needs_drop::<T>() || self.dtor_registered.get() {
+        if !mem::needs_drop::<T>() || self.dtor_registered.get() {
             return
         }
 
@@ -128,7 +128,7 @@ unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
     register_dtor_fallback(t, dtor);
 }
 
-// OSX's analog of the above linux function is this _tlv_atexit function.
+// macOS's analog of the above linux function is this _tlv_atexit function.
 // The disassembly of thread_local globals in C++ (at least produced by
 // clang) will have this show up in the output.
 #[cfg(target_os = "macos")]
@@ -154,17 +154,17 @@ pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
     // `None`.
     (*ptr).dtor_running.set(true);
 
-    // The OSX implementation of TLS apparently had an odd aspect to it
+    // The macOS implementation of TLS apparently had an odd aspect to it
     // where the pointer we have may be overwritten while this destructor
     // is running. Specifically if a TLS destructor re-accesses TLS it may
     // trigger a re-initialization of all TLS variables, paving over at
     // least some destroyed ones with initial values.
     //
-    // This means that if we drop a TLS value in place on OSX that we could
+    // This means that if we drop a TLS value in place on macOS that we could
     // revert the value to its original state halfway through the
     // destructor, which would be bad!
     //
-    // Hence, we use `ptr::read` on OSX (to move to a "safe" location)
+    // Hence, we use `ptr::read` on macOS (to move to a "safe" location)
     // instead of drop_in_place.
     if cfg!(target_os = "macos") {
         ptr::read((*ptr).inner.get());
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index c690fd467ee..405fac2b9d7 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -29,7 +29,7 @@ fn max_len() -> usize {
     // with the man page quoting that if the count of bytes to read is
     // greater than `SSIZE_MAX` the result is "unspecified".
     //
-    // On OSX, however, apparently the 64-bit libc is either buggy or
+    // On macOS, however, apparently the 64-bit libc is either buggy or
     // intentionally showing odd behavior by rejecting any read with a size
     // larger than or equal to INT_MAX. To handle both of these the read
     // size is capped on both platforms.
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index d0fb96b1ff1..e893a139094 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -439,7 +439,7 @@ impl File {
         // Linux kernel then the flag is just ignored by the OS, so we continue
         // to explicitly ask for a CLOEXEC fd here.
         //
-        // The CLOEXEC flag, however, is supported on versions of OSX/BSD/etc
+        // The CLOEXEC flag, however, is supported on versions of macOS/BSD/etc
         // that we support, so we only do this on Linux currently.
         if cfg!(target_os = "linux") {
             fd.set_cloexec()?;
@@ -573,7 +573,7 @@ impl fmt::Debug for File {
         #[cfg(target_os = "macos")]
         fn get_path(fd: c_int) -> Option<PathBuf> {
             // FIXME: The use of PATH_MAX is generally not encouraged, but it
-            // is inevitable in this case because OS X defines `fcntl` with
+            // is inevitable in this case because macOS defines `fcntl` with
             // `F_GETPATH` in terms of `MAXPATHLEN`, and there are no
             // alternatives. If a better method is invented, it should be used
             // instead.
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index c57751a01d7..854d380d128 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -92,7 +92,7 @@ pub fn init() {
 
     #[cfg(not(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia")))]
     unsafe fn reset_sigpipe() {
-        assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != !0);
+        assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
     }
     #[cfg(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia"))]
     unsafe fn reset_sigpipe() {}
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 36928696c40..8e41fd009be 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -253,7 +253,12 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(any(target_os = "linux", target_os = "android", target_os = "emscripten"))]
 pub fn current_exe() -> io::Result<PathBuf> {
-    ::fs::read_link("/proc/self/exe")
+    let selfexe = PathBuf::from("/proc/self/exe");
+    if selfexe.exists() {
+        ::fs::read_link(selfexe)
+    } else {
+        Err(io::Error::new(io::ErrorKind::Other, "no /proc/self/exe available. Is /proc mounted?"))
+    }
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios"))]
diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs
index c27599ec020..f5b942d3343 100644
--- a/src/libstd/sys/unix/os_str.rs
+++ b/src/libstd/sys/unix/os_str.rs
@@ -104,6 +104,12 @@ impl Buf {
     pub fn into_box(self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_boxed_slice()) }
     }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Buf { inner: inner.into_vec() }
+    }
 }
 
 impl Slice {
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 51e00fc1ab9..706256ff10e 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use cmp;
 use io;
 use libc::{self, c_int};
 use mem;
-use ptr;
 use sys::{cvt, cvt_r};
 use sys::fd::FileDesc;
 
@@ -80,16 +78,14 @@ pub fn read2(p1: AnonPipe,
     p1.set_nonblocking(true)?;
     p2.set_nonblocking(true)?;
 
-    let max = cmp::max(p1.raw(), p2.raw());
+    let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };
+    fds[0].fd = p1.raw();
+    fds[0].events = libc::POLLIN;
+    fds[1].fd = p2.raw();
+    fds[1].events = libc::POLLIN;
     loop {
-        // wait for either pipe to become readable using `select`
-        cvt_r(|| unsafe {
-            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, ptr::null_mut(), ptr::null_mut(),
-                         ptr::null_mut())
-        })?;
+        // wait for either pipe to become readable using `poll`
+        cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;
 
         // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
         // EAGAIN. If we hit EOF, then this will happen because the underlying
@@ -109,11 +105,11 @@ pub fn read2(p1: AnonPipe,
                 }
             }
         };
-        if read(&p1, v1)? {
+        if fds[0].revents != 0 && read(&p1, v1)? {
             p2.set_nonblocking(false)?;
             return p2.read_to_end(v2).map(|_| ());
         }
-        if read(&p2, v2)? {
+        if fds[1].revents != 0 && read(&p2, v2)? {
             p1.set_nonblocking(false)?;
             return p1.read_to_end(v1).map(|_| ());
         }
diff --git a/src/libstd/sys/unix/process/magenta.rs b/src/libstd/sys/unix/process/magenta.rs
index 07f29784df6..5b5e29c0374 100644
--- a/src/libstd/sys/unix/process/magenta.rs
+++ b/src/libstd/sys/unix/process/magenta.rs
@@ -202,7 +202,7 @@ pub const LP_CLONE_MXIO_CWD: u32 = 0x0002;
 
 // ERR_NO_RESOURCES: The system was not able to allocate some resource
 // needed for the operation.
-#[allow(unused)] pub const ERR_NO_RESOURCES: mx_status_t = -5;
+#[allow(unused)] pub const ERR_NO_RESOURCES: mx_status_t = -3;
 
 // ERR_NO_MEMORY: The system was not able to allocate memory needed
 // for the operation.
@@ -210,30 +210,34 @@ pub const LP_CLONE_MXIO_CWD: u32 = 0x0002;
 
 // ERR_CALL_FAILED: The second phase of mx_channel_call(; did not complete
 // successfully.
-#[allow(unused)] pub const ERR_CALL_FAILED: mx_status_t = -53;
+#[allow(unused)] pub const ERR_CALL_FAILED: mx_status_t = -5;
+
+// ERR_INTERRUPTED_RETRY: The system call was interrupted, but should be
+// retried.  This should not be seen outside of the VDSO.
+#[allow(unused)] pub const ERR_INTERRUPTED_RETRY: mx_status_t = -6;
 
 // ======= Parameter errors =======
 // ERR_INVALID_ARGS: an argument is invalid, ex. null pointer
 #[allow(unused)] pub const ERR_INVALID_ARGS: mx_status_t = -10;
 
+// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
+#[allow(unused)] pub const ERR_BAD_HANDLE: mx_status_t = -11;
+
 // ERR_WRONG_TYPE: The subject of the operation is the wrong type to
 // perform the operation.
 // Example: Attempting a message_read on a thread handle.
-#[allow(unused)] pub const ERR_WRONG_TYPE: mx_status_t = -54;
+#[allow(unused)] pub const ERR_WRONG_TYPE: mx_status_t = -12;
 
 // ERR_BAD_SYSCALL: The specified syscall number is invalid.
-#[allow(unused)] pub const ERR_BAD_SYSCALL: mx_status_t = -11;
-
-// ERR_BAD_HANDLE: A specified handle value does not refer to a handle.
-#[allow(unused)] pub const ERR_BAD_HANDLE: mx_status_t = -12;
+#[allow(unused)] pub const ERR_BAD_SYSCALL: mx_status_t = -13;
 
 // ERR_OUT_OF_RANGE: An argument is outside the valid range for this
 // operation.
-#[allow(unused)] pub const ERR_OUT_OF_RANGE: mx_status_t = -13;
+#[allow(unused)] pub const ERR_OUT_OF_RANGE: mx_status_t = -14;
 
 // ERR_BUFFER_TOO_SMALL: A caller provided buffer is too small for
 // this operation.
-#[allow(unused)] pub const ERR_BUFFER_TOO_SMALL: mx_status_t = -14;
+#[allow(unused)] pub const ERR_BUFFER_TOO_SMALL: mx_status_t = -15;
 
 // ======= Precondition or state errors =======
 // ERR_BAD_STATE: operation failed because the current state of the
@@ -241,47 +245,48 @@ pub const LP_CLONE_MXIO_CWD: u32 = 0x0002;
 // not satisfied
 #[allow(unused)] pub const ERR_BAD_STATE: mx_status_t = -20;
 
+// ERR_TIMED_OUT: The time limit for the operation elapsed before
+// the operation completed.
+#[allow(unused)] pub const ERR_TIMED_OUT: mx_status_t = -21;
+
+// ERR_SHOULD_WAIT: The operation cannot be performed currently but
+// potentially could succeed if the caller waits for a prerequisite
+// to be satisfied, for example waiting for a handle to be readable
+// or writable.
+// Example: Attempting to read from a message pipe that has no
+// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
+// Attempting to read from a message pipe that has no messages waiting
+// and has a closed remote end will return ERR_REMOTE_CLOSED.
+#[allow(unused)] pub const ERR_SHOULD_WAIT: mx_status_t = -22;
+
+// ERR_CANCELED: The in-progress operation (e.g. a wait) has been
+// // canceled.
+#[allow(unused)] pub const ERR_CANCELED: mx_status_t = -23;
+
+// ERR_PEER_CLOSED: The operation failed because the remote end
+// of the subject of the operation was closed.
+#[allow(unused)] pub const ERR_PEER_CLOSED: mx_status_t = -24;
+
 // ERR_NOT_FOUND: The requested entity is not found.
-#[allow(unused)] pub const ERR_NOT_FOUND: mx_status_t = -3;
+#[allow(unused)] pub const ERR_NOT_FOUND: mx_status_t = -25;
 
 // ERR_ALREADY_EXISTS: An object with the specified identifier
 // already exists.
 // Example: Attempting to create a file when a file already exists
 // with that name.
-#[allow(unused)] pub const ERR_ALREADY_EXISTS: mx_status_t = -15;
+#[allow(unused)] pub const ERR_ALREADY_EXISTS: mx_status_t = -26;
 
 // ERR_ALREADY_BOUND: The operation failed because the named entity
 // is already owned or controlled by another entity. The operation
 // could succeed later if the current owner releases the entity.
-#[allow(unused)] pub const ERR_ALREADY_BOUND: mx_status_t = -16;
-
-// ERR_TIMED_OUT: The time limit for the operation elapsed before
-// the operation completed.
-#[allow(unused)] pub const ERR_TIMED_OUT: mx_status_t = -23;
-
-// ERR_HANDLE_CLOSED: a handle being waited on was closed
-#[allow(unused)] pub const ERR_HANDLE_CLOSED: mx_status_t = -24;
-
-// ERR_REMOTE_CLOSED: The operation failed because the remote end
-// of the subject of the operation was closed.
-#[allow(unused)] pub const ERR_REMOTE_CLOSED: mx_status_t = -25;
+#[allow(unused)] pub const ERR_ALREADY_BOUND: mx_status_t = -27;
 
 // ERR_UNAVAILABLE: The subject of the operation is currently unable
 // to perform the operation.
 // Note: This is used when there's no direct way for the caller to
 // observe when the subject will be able to perform the operation
 // and should thus retry.
-#[allow(unused)] pub const ERR_UNAVAILABLE: mx_status_t = -26;
-
-// ERR_SHOULD_WAIT: The operation cannot be performed currently but
-// potentially could succeed if the caller waits for a prerequisite
-// to be satisfied, for example waiting for a handle to be readable
-// or writable.
-// Example: Attempting to read from a message pipe that has no
-// messages waiting but has an open remote will return ERR_SHOULD_WAIT.
-// Attempting to read from a message pipe that has no messages waiting
-// and has a closed remote end will return ERR_REMOTE_CLOSED.
-#[allow(unused)] pub const ERR_SHOULD_WAIT: mx_status_t = -27;
+#[allow(unused)] pub const ERR_UNAVAILABLE: mx_status_t = -28;
 
 // ======= Permission check errors =======
 // ERR_ACCESS_DENIED: The caller did not have permission to perform
@@ -312,3 +317,7 @@ pub const LP_CLONE_MXIO_CWD: u32 = 0x0002;
 #[allow(unused)] pub const ERR_BAD_PATH: mx_status_t = -50;
 #[allow(unused)] pub const ERR_NOT_DIR: mx_status_t = -51;
 #[allow(unused)] pub const ERR_NOT_FILE: mx_status_t = -52;
+// ERR_FILE_BIG: A file exceeds a filesystem-specific size limit.
+#[allow(unused)] pub const ERR_FILE_BIG: mx_status_t = -53;
+// ERR_NO_SPACE: Filesystem or device space is exhausted.
+#[allow(unused)] pub const ERR_NO_SPACE: mx_status_t = -54;
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index a4536520376..e9f41009064 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -417,13 +417,27 @@ mod tests {
         }
     }
 
+    // Android with api less than 21 define sig* functions inline, so it is not
+    // available for dynamic link. Implementing sigemptyset and sigaddset allow us
+    // to support older Android version (independent of libc version).
+    // The following implementations are based on https://git.io/vSkNf
+
     #[cfg(not(target_os = "android"))]
     extern {
+        #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
+        fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
+
         #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
         fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
     }
 
     #[cfg(target_os = "android")]
+    unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
+        libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>());
+        return 0;
+    }
+
+    #[cfg(target_os = "android")]
     unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
         use slice;
 
@@ -434,8 +448,8 @@ mod tests {
     }
 
     // See #14232 for more information, but it appears that signal delivery to a
-    // newly spawned process may just be raced in the OSX, so to prevent this
-    // test from being flaky we ignore it on OSX.
+    // newly spawned process may just be raced in the macOS, so to prevent this
+    // test from being flaky we ignore it on macOS.
     #[test]
     #[cfg_attr(target_os = "macos", ignore)]
     #[cfg_attr(target_os = "nacl", ignore)] // no signals on NaCl.
@@ -450,7 +464,7 @@ mod tests {
 
             let mut set: libc::sigset_t = mem::uninitialized();
             let mut old_set: libc::sigset_t = mem::uninitialized();
-            t!(cvt(libc::sigemptyset(&mut set)));
+            t!(cvt(sigemptyset(&mut set)));
             t!(cvt(sigaddset(&mut set, libc::SIGINT)));
             t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
 
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index bbc987209e3..edd322ca6fa 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -129,7 +129,7 @@ impl Command {
     // mutex, and then after the fork they unlock it.
     //
     // Despite this information, libnative's spawn has been witnessed to
-    // deadlock on both OSX and FreeBSD. I'm not entirely sure why, but
+    // deadlock on both macOS and FreeBSD. I'm not entirely sure why, but
     // all collected backtraces point at malloc/free traffic in the
     // child spawned process.
     //
@@ -193,7 +193,16 @@ impl Command {
             // need to clean things up now to avoid confusing the program
             // we're about to run.
             let mut set: libc::sigset_t = mem::uninitialized();
-            t!(cvt(libc::sigemptyset(&mut set)));
+            if cfg!(target_os = "android") {
+                // Implementing sigemptyset allow us to support older Android
+                // versions. See the comment about Android and sig* functions in
+                // process_common.rs
+                libc::memset(&mut set as *mut _ as *mut _,
+                             0,
+                             mem::size_of::<libc::sigset_t>());
+            } else {
+                t!(cvt(libc::sigemptyset(&mut set)));
+            }
             t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set,
                                          ptr::null_mut())));
             let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL);
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 22d47ba0f62..51adbc24ae0 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -187,7 +187,7 @@ mod imp {
             let stack =  libc::stack_t {
                 ss_sp: ptr::null_mut(),
                 ss_flags: SS_DISABLE,
-                // Workaround for bug in MacOS implementation of sigaltstack
+                // Workaround for bug in macOS implementation of sigaltstack
                 // UNIX2003 which returns ENOMEM when disabling a stack while
                 // passing ss_size smaller than MINSIGSTKSZ. According to POSIX
                 // both ss_sp and ss_size should be ignored in this case.
diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local.rs
index d22118d4d79..2487f6bcaf7 100644
--- a/src/libstd/sys/unix/thread_local.rs
+++ b/src/libstd/sys/unix/thread_local.rs
@@ -38,3 +38,8 @@ pub unsafe fn destroy(key: Key) {
     let r = libc::pthread_key_delete(key);
     debug_assert_eq!(r, 0);
 }
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    false
+}
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index a08cec38f73..a1ad94872de 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -157,7 +157,7 @@ mod inner {
         pub fn sub_duration(&self, other: &Duration) -> Instant {
             Instant {
                 t: self.t.checked_sub(dur2intervals(other))
-                       .expect("overflow when adding duration to instant"),
+                       .expect("overflow when subtracting duration from instant"),
             }
         }
     }
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 4daab31c28f..1646f8cce72 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -14,8 +14,9 @@
 #![cfg_attr(test, allow(dead_code))]
 #![unstable(issue = "0", feature = "windows_c")]
 
-use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort,};
-use os::raw::{c_char, c_ulonglong};
+use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort, c_char};
+#[cfg(target_arch = "x86_64")]
+use os::raw::c_ulonglong;
 use libc::{wchar_t, size_t, c_void};
 use ptr;
 
@@ -45,7 +46,7 @@ pub type SIZE_T = usize;
 pub type WORD = u16;
 pub type CHAR = c_char;
 pub type HCRYPTPROV = LONG_PTR;
-pub type ULONG_PTR = c_ulonglong;
+pub type ULONG_PTR = usize;
 pub type ULONG = c_ulong;
 #[cfg(target_arch = "x86_64")]
 pub type ULONGLONG = u64;
@@ -198,7 +199,10 @@ pub const ERROR_TIMEOUT: DWORD = 0x5B4;
 
 pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
 
+pub const FACILITY_NT_BIT: DWORD = 0x1000_0000;
+
 pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
 pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
 
 pub const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
@@ -935,7 +939,6 @@ extern "system" {
                           args: *const c_void)
                           -> DWORD;
     pub fn TlsAlloc() -> DWORD;
-    pub fn TlsFree(dwTlsIndex: DWORD) -> BOOL;
     pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
     pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
     pub fn GetLastError() -> DWORD;
diff --git a/src/libstd/sys/windows/ext/ffi.rs b/src/libstd/sys/windows/ext/ffi.rs
index 253787546c1..3f6c2827a3f 100644
--- a/src/libstd/sys/windows/ext/ffi.rs
+++ b/src/libstd/sys/windows/ext/ffi.rs
@@ -26,8 +26,22 @@ pub trait OsStringExt {
     /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
     /// 16-bit code units.
     ///
-    /// This is lossless: calling `.encode_wide()` on the resulting string
+    /// This is lossless: calling [`encode_wide`] on the resulting string
     /// will always return the original code units.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsString;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// // UTF-16 encoding for "Unicode".
+    /// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
+    ///
+    /// let string = OsString::from_wide(&source[..]);
+    /// ```
+    ///
+    /// [`encode_wide`]: ./trait.OsStrExt.html#tymethod.encode_wide
     #[stable(feature = "rust1", since = "1.0.0")]
     fn from_wide(wide: &[u16]) -> Self;
 }
@@ -42,11 +56,29 @@ impl OsStringExt for OsString {
 /// Windows-specific extensions to `OsStr`.
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait OsStrExt {
-    /// Re-encodes an `OsStr` as a wide character sequence,
-    /// i.e. potentially ill-formed UTF-16.
+    /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially
+    /// ill-formed UTF-16.
+    ///
+    /// This is lossless: calling [`OsString::from_wide`] and then
+    /// `encode_wide` on the result will yield the original code units.
+    /// Note that the encoding does not add a final null terminator.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ffi::OsString;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// // UTF-16 encoding for "Unicode".
+    /// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
+    ///
+    /// let string = OsString::from_wide(&source[..]);
+    ///
+    /// let result: Vec<u16> = string.encode_wide().collect();
+    /// assert_eq!(&source[..], &result[..]);
+    /// ```
     ///
-    /// This is lossless. Note that the encoding does not include a final
-    /// null.
+    /// [`OsString::from_wide`]: ./trait.OsStringExt.html#tymethod.from_wide
     #[stable(feature = "rust1", since = "1.0.0")]
     fn encode_wide(&self) -> EncodeWide;
 }
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index c63dd8a47ca..2d00cb38ec4 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Windows-specific extensions for the primitives in `std::fs`
+//! Windows-specific extensions for the primitives in the `std::fs` module.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
@@ -18,7 +18,9 @@ use path::Path;
 use sys;
 use sys_common::{AsInnerMut, AsInner};
 
-/// Windows-specific extensions to `File`
+/// Windows-specific extensions to [`File`].
+///
+/// [`File`]: ../../../fs/struct.File.html
 #[stable(feature = "file_offset", since = "1.15.0")]
 pub trait FileExt {
     /// Seeks to a given position and reads a number of bytes.
@@ -35,6 +37,24 @@ pub trait FileExt {
     /// Note that similar to `File::read`, it is not an error to return with a
     /// short read. When returning from such a short read, the file pointer is
     /// still updated.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs::File;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let mut file = File::open("foo.txt")?;
+    /// let mut buffer = [0; 10];
+    ///
+    /// // Read 10 bytes, starting 72 bytes from the
+    /// // start of the file.
+    /// file.seek_read(&mut buffer[..], 72)?;
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
 
@@ -52,6 +72,22 @@ pub trait FileExt {
     /// Note that similar to `File::write`, it is not an error to return a
     /// short write. When returning from such a short write, the file pointer
     /// is still updated.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut buffer = File::create("foo.txt")?;
+    ///
+    /// // Write a byte string starting 72 bytes from
+    /// // the start of the file.
+    /// buffer.seek_write(b"some bytes", 72)?;
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
 }
@@ -67,84 +103,97 @@ impl FileExt for fs::File {
     }
 }
 
-/// Windows-specific extensions to `OpenOptions`
+/// Windows-specific extensions to [`OpenOptions`].
+///
+/// [`OpenOptions`]: ../../../fs/struct.OpenOptions.html
 #[stable(feature = "open_options_ext", since = "1.10.0")]
 pub trait OpenOptionsExt {
-    /// Overrides the `dwDesiredAccess` argument to the call to `CreateFile`
+    /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
     /// with the specified value.
     ///
     /// This will override the `read`, `write`, and `append` flags on the
     /// `OpenOptions` structure. This method provides fine-grained control over
     /// the permissions to read, write and append data, attributes (like hidden
-    /// and system) and extended attributes.
+    /// and system), and extended attributes.
     ///
     /// # Examples
     ///
     /// ```no_run
     /// use std::fs::OpenOptions;
-    /// use std::os::windows::fs::OpenOptionsExt;
+    /// use std::os::windows::prelude::*;
     ///
     /// // Open without read and write permission, for example if you only need
-    /// // to call `stat()` on the file
+    /// // to call `stat` on the file
     /// let file = OpenOptions::new().access_mode(0).open("foo.txt");
     /// ```
+    ///
+    /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
     #[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
+    /// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
     /// the specified value.
     ///
     /// By default `share_mode` is set to
-    /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. Specifying
-    /// less permissions denies others to read from, write to and/or delete the
-    /// file while it is open.
+    /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
+    /// other processes to to read, write, and delete/rename the same file
+    /// while it is open. Removing any of the flags will prevent other
+    /// processes from performing the corresponding operation until the file
+    /// handle is closed.
     ///
     /// # Examples
     ///
     /// ```no_run
     /// use std::fs::OpenOptions;
-    /// use std::os::windows::fs::OpenOptionsExt;
+    /// use std::os::windows::prelude::*;
     ///
     /// // Do not allow others to read or modify this file while we have it open
-    /// // for writing
-    /// let file = OpenOptions::new().write(true)
-    ///                              .share_mode(0)
-    ///                              .open("foo.txt");
+    /// // for writing.
+    /// let file = OpenOptions::new()
+    ///     .write(true)
+    ///     .share_mode(0)
+    ///     .open("foo.txt");
     /// ```
+    ///
+    /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
     #[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
-    /// `CreateFile2` (or combines it with `attributes` and `security_qos_flags`
-    /// to set the `dwFlagsAndAttributes` for `CreateFile`).
+    /// [`CreateFile2`] to the specified value (or combines it with
+    /// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
+    /// for [`CreateFile`]).
     ///
-    /// Custom flags can only set flags, not remove flags set by Rusts options.
-    /// This options overwrites any previously set custom flags.
+    /// Custom flags can only set flags, not remove flags set by Rust's options.
+    /// This option overwrites any previously set custom flags.
     ///
     /// # Examples
     ///
-    /// ```rust,ignore
+    /// ```ignore
     /// extern crate winapi;
+    ///
     /// use std::fs::OpenOptions;
-    /// use std::os::windows::fs::OpenOptionsExt;
-    ///
-    /// let mut options = OpenOptions::new();
-    /// options.create(true).write(true);
-    /// if cfg!(windows) {
-    ///     options.custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE);
-    /// }
-    /// let file = options.open("foo.txt");
+    /// use std::os::windows::prelude::*;
+    ///
+    /// let file = OpenOptions::new()
+    ///     .create(true)
+    ///     .write(true)
+    ///     .custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE)
+    ///     .open("foo.txt");
     /// ```
+    ///
+    /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
+    /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
     #[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
+    /// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
     /// the specified value (or combines it with `custom_flags` and
     /// `security_qos_flags` to set the `dwFlagsAndAttributes` for
-    /// `CreateFile`).
+    /// [`CreateFile`]).
     ///
     /// If a _new_ file is created because it does not yet exist and
-    ///`.create(true)` or `.create_new(true)` are specified, the new file is
+    /// `.create(true)` or `.create_new(true)` are specified, the new file is
     /// given the attributes declared with `.attributes()`.
     ///
     /// If an _existing_ file is opened with `.create(true).truncate(true)`, its
@@ -155,21 +204,52 @@ pub trait OpenOptionsExt {
     ///
     /// # Examples
     ///
-    /// ```rust,ignore
+    /// ```ignore
     /// extern crate winapi;
+    ///
     /// use std::fs::OpenOptions;
-    /// use std::os::windows::fs::OpenOptionsExt;
+    /// use std::os::windows::prelude::*;
     ///
-    /// let file = OpenOptions::new().write(true).create(true)
-    ///                              .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
-    ///                              .open("foo.txt");
+    /// let file = OpenOptions::new()
+    ///     .write(true)
+    ///     .create(true)
+    ///     .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
+    ///     .open("foo.txt");
     /// ```
+    ///
+    /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
+    /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
     #[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
+    /// 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`).
+    /// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
+    ///
+    /// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For
+    /// information about possible values, see [Impersonation Levels] on the
+    /// Windows Dev Center site.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs::OpenOptions;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// let file = OpenOptions::new()
+    ///     .write(true)
+    ///     .create(true)
+    ///
+    ///     // Sets the flag value to `SecurityIdentification`.
+    ///     .security_qos_flags(1)
+    ///
+    ///     .open("foo.txt");
+    /// ```
+    ///
+    /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
+    /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
+    /// [Impersonation Levels]:
+    ///     https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx
     #[stable(feature = "open_options_ext", since = "1.10.0")]
     fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
 }
@@ -197,35 +277,136 @@ impl OpenOptionsExt for OpenOptions {
     }
 }
 
-/// Extension methods for `fs::Metadata` to access the raw fields contained
+/// Extension methods for [`fs::Metadata`] to access the raw fields contained
 /// within.
+///
+/// The data members that this trait exposes correspond to the members
+/// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
+///
+/// [`fs::Metadata`]: ../../../fs/struct.Metadata.html
+/// [`BY_HANDLE_FILE_INFORMATION`]:
+///     https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx
 #[stable(feature = "metadata_ext", since = "1.1.0")]
 pub trait MetadataExt {
     /// Returns the value of the `dwFileAttributes` field of this metadata.
     ///
     /// This field contains the file system attribute information for a file
-    /// or directory.
+    /// or directory. For possible values and their descriptions, see
+    /// [File Attribute Constants] in the Windows Dev Center.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let metadata = fs::metadata("foo.txt")?;
+    /// let attributes = metadata.file_attributes();
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// [File Attribute Constants]:
+    ///     https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn file_attributes(&self) -> u32;
 
     /// Returns the value of the `ftCreationTime` field of this metadata.
     ///
-    /// The returned 64-bit value represents the number of 100-nanosecond
-    /// intervals since January 1, 1601 (UTC).
+    /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
+    /// which represents the number of 100-nanosecond intervals since
+    /// January 1, 1601 (UTC). The struct is automatically
+    /// converted to a `u64` value, as that is the recommended way
+    /// to use it.
+    ///
+    /// If the underlying filesystem does not support creation time, the
+    /// returned value is 0.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let metadata = fs::metadata("foo.txt")?;
+    /// let creation_time = metadata.creation_time();
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn creation_time(&self) -> u64;
 
     /// Returns the value of the `ftLastAccessTime` field of this metadata.
     ///
-    /// The returned 64-bit value represents the number of 100-nanosecond
-    /// intervals since January 1, 1601 (UTC).
+    /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
+    /// which represents the number of 100-nanosecond intervals since
+    /// January 1, 1601 (UTC). The struct is automatically
+    /// converted to a `u64` value, as that is the recommended way
+    /// to use it.
+    ///
+    /// For a file, the value specifies the last time that a file was read
+    /// from or written to. For a directory, the value specifies when
+    /// the directory was created. For both files and directories, the
+    /// specified date is correct, but the time of day is always set to
+    /// midnight.
+    ///
+    /// If the underlying filesystem does not support last access time, the
+    /// returned value is 0.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let metadata = fs::metadata("foo.txt")?;
+    /// let last_access_time = metadata.last_access_time();
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn last_access_time(&self) -> u64;
 
     /// Returns the value of the `ftLastWriteTime` field of this metadata.
     ///
-    /// The returned 64-bit value represents the number of 100-nanosecond
-    /// intervals since January 1, 1601 (UTC).
+    /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
+    /// which represents the number of 100-nanosecond intervals since
+    /// January 1, 1601 (UTC). The struct is automatically
+    /// converted to a `u64` value, as that is the recommended way
+    /// to use it.
+    ///
+    /// For a file, the value specifies the last time that a file was written
+    /// to. For a directory, the structure specifies when the directory was
+    /// created.
+    ///
+    /// If the underlying filesystem does not support the last write time
+    /// time, the returned value is 0.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let metadata = fs::metadata("foo.txt")?;
+    /// let last_write_time = metadata.last_write_time();
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn last_write_time(&self) -> u64;
 
@@ -233,6 +414,20 @@ pub trait MetadataExt {
     /// metadata.
     ///
     /// The returned value does not have meaning for directories.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::io;
+    /// use std::fs;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// # fn foo() -> io::Result<()> {
+    /// let metadata = fs::metadata("foo.txt")?;
+    /// let file_size = metadata.file_size();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn file_size(&self) -> u64;
 }
@@ -253,7 +448,7 @@ impl MetadataExt for Metadata {
 ///
 /// # Examples
 ///
-/// ```ignore
+/// ```no_run
 /// use std::os::windows::fs;
 ///
 /// # fn foo() -> std::io::Result<()> {
@@ -274,7 +469,7 @@ pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
 ///
 /// # Examples
 ///
-/// ```ignore
+/// ```no_run
 /// use std::os::windows::fs;
 ///
 /// # fn foo() -> std::io::Result<()> {
diff --git a/src/libstd/sys/windows/ext/mod.rs b/src/libstd/sys/windows/ext/mod.rs
index f12e50cc923..11b1337a8ae 100644
--- a/src/libstd/sys/windows/ext/mod.rs
+++ b/src/libstd/sys/windows/ext/mod.rs
@@ -8,11 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Experimental extensions to `std` for Windows.
+//! Platform-specific extensions to `std` for Windows.
 //!
-//! For now, this module is limited to extracting handles, file
-//! descriptors, and sockets, but its functionality will grow over
-//! time.
+//! Provides access to platform-level information for Windows, and exposes
+//! Windows-specific idioms that would otherwise be inappropriate as part
+//! the core `std` library. These extensions allow developers to use
+//! `std` types and idioms with Windows in a way that the normal
+//! platform-agnostic idioms would not normally support.
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libstd/sys/windows/ext/process.rs b/src/libstd/sys/windows/ext/process.rs
index 1419a4af427..759f055c4b1 100644
--- a/src/libstd/sys/windows/ext/process.rs
+++ b/src/libstd/sys/windows/ext/process.rs
@@ -104,6 +104,7 @@ pub trait CommandExt {
     /// Sets the [process creation flags][1] to be passed to `CreateProcess`.
     ///
     /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
+    ///
     /// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
     #[stable(feature = "windows_process_extensions", since = "1.16.0")]
     fn creation_flags(&mut self, flags: u32) -> &mut process::Command;
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 7e28dd1e259..a51b458451e 100644
--- a/src/libstd/sys/windows/os.rs
+++ b/src/libstd/sys/windows/os.rs
@@ -32,7 +32,7 @@ pub fn errno() -> i32 {
 }
 
 /// Gets a detailed string description for the given error number.
-pub fn error_string(errnum: i32) -> String {
+pub fn error_string(mut errnum: i32) -> String {
     // This value is calculated from the macro
     // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
     let langId = 0x0800 as c::DWORD;
@@ -40,9 +40,27 @@ pub fn error_string(errnum: i32) -> String {
     let mut buf = [0 as c::WCHAR; 2048];
 
     unsafe {
-        let res = c::FormatMessageW(c::FORMAT_MESSAGE_FROM_SYSTEM |
+        let mut module = ptr::null_mut();
+        let mut flags = 0;
+
+        // NTSTATUS errors may be encoded as HRESULT, which may returned from
+        // GetLastError. For more information about Windows error codes, see
+        // `[MS-ERREF]`: https://msdn.microsoft.com/en-us/library/cc231198.aspx
+        if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
+            // format according to https://support.microsoft.com/en-us/help/259693
+            const NTDLL_DLL: &'static [u16] = &['N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _,
+                                                '.' as _, 'D' as _, 'L' as _, 'L' as _, 0];
+            module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
+
+            if module != ptr::null_mut() {
+                errnum ^= c::FACILITY_NT_BIT as i32;
+                flags = c::FORMAT_MESSAGE_FROM_HMODULE;
+            }
+        }
+
+        let res = c::FormatMessageW(flags | c::FORMAT_MESSAGE_FROM_SYSTEM |
                                         c::FORMAT_MESSAGE_IGNORE_INSERTS,
-                                    ptr::null_mut(),
+                                    module,
                                     errnum as c::DWORD,
                                     langId,
                                     buf.as_mut_ptr(),
@@ -299,3 +317,17 @@ pub fn home_dir() -> Option<PathBuf> {
 pub fn exit(code: i32) -> ! {
     unsafe { c::ExitProcess(code as c::UINT) }
 }
+
+#[cfg(test)]
+mod tests {
+    use io::Error;
+    use sys::c;
+
+    // tests `error_string` above
+    #[test]
+    fn ntstatus_error() {
+        const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001;
+        assert!(!Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _)
+            .to_string().contains("FormatMessageW() returned error"));
+    }
+}
diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs
index b02b06e1ef2..f401e7b35c8 100644
--- a/src/libstd/sys/windows/os_str.rs
+++ b/src/libstd/sys/windows/os_str.rs
@@ -97,6 +97,12 @@ impl Buf {
     pub fn into_box(self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_box()) }
     }
+
+    #[inline]
+    pub fn from_box(boxed: Box<Slice>) -> Buf {
+        let inner: Box<Wtf8> = unsafe { mem::transmute(boxed) };
+        Buf { inner: Wtf8Buf::from_box(inner) }
+    }
 }
 
 impl Slice {
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 1afb3728c9d..dfbc1b581ee 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -257,8 +257,13 @@ impl Stdio {
             // INVALID_HANDLE_VALUE.
             Stdio::Inherit => {
                 match stdio::get(stdio_id) {
-                    Ok(io) => io.handle().duplicate(0, true,
-                                                    c::DUPLICATE_SAME_ACCESS),
+                    Ok(io) => {
+                        let io = Handle::new(io.handle());
+                        let ret = io.duplicate(0, true,
+                                               c::DUPLICATE_SAME_ACCESS);
+                        io.into_raw();
+                        return ret
+                    }
                     Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)),
                 }
             }
diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs
index b1a57c349fb..d72e4b4438b 100644
--- a/src/libstd/sys/windows/stdio.rs
+++ b/src/libstd/sys/windows/stdio.rs
@@ -22,42 +22,43 @@ use sys::cvt;
 use sys::handle::Handle;
 use sys_common::io::read_to_end_uninitialized;
 
-pub struct NoClose(Option<Handle>);
-
 pub enum Output {
-    Console(NoClose),
-    Pipe(NoClose),
+    Console(c::HANDLE),
+    Pipe(c::HANDLE),
 }
 
 pub struct Stdin {
-    handle: Output,
     utf8: Mutex<io::Cursor<Vec<u8>>>,
 }
-pub struct Stdout(Output);
-pub struct Stderr(Output);
+pub struct Stdout;
+pub struct Stderr;
 
 pub fn get(handle: c::DWORD) -> io::Result<Output> {
     let handle = unsafe { c::GetStdHandle(handle) };
     if handle == c::INVALID_HANDLE_VALUE {
         Err(io::Error::last_os_error())
     } else if handle.is_null() {
-        Err(io::Error::new(io::ErrorKind::Other,
-                           "no stdio handle available for this process"))
+        Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
     } else {
-        let ret = NoClose::new(handle);
         let mut out = 0;
         match unsafe { c::GetConsoleMode(handle, &mut out) } {
-            0 => Ok(Output::Pipe(ret)),
-            _ => Ok(Output::Console(ret)),
+            0 => Ok(Output::Pipe(handle)),
+            _ => Ok(Output::Console(handle)),
         }
     }
 }
 
-fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
-    let handle = match *out {
-        Output::Console(ref c) => c.get().raw(),
-        Output::Pipe(ref p) => return p.get().write(data),
+fn write(handle: c::DWORD, data: &[u8]) -> io::Result<usize> {
+    let handle = match try!(get(handle)) {
+        Output::Console(c) => c,
+        Output::Pipe(p) => {
+            let handle = Handle::new(p);
+            let ret = handle.write(data);
+            handle.into_raw();
+            return ret
+        }
     };
+
     // As with stdin on windows, stdout often can't handle writes of large
     // sizes. For an example, see #14940. For this reason, don't try to
     // write the entire output buffer on windows.
@@ -93,18 +94,20 @@ fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
 
 impl Stdin {
     pub fn new() -> io::Result<Stdin> {
-        get(c::STD_INPUT_HANDLE).map(|handle| {
-            Stdin {
-                handle: handle,
-                utf8: Mutex::new(Cursor::new(Vec::new())),
-            }
+        Ok(Stdin {
+            utf8: Mutex::new(Cursor::new(Vec::new())),
         })
     }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
-        let handle = match self.handle {
-            Output::Console(ref c) => c.get().raw(),
-            Output::Pipe(ref p) => return p.get().read(buf),
+        let handle = match try!(get(c::STD_INPUT_HANDLE)) {
+            Output::Console(c) => c,
+            Output::Pipe(p) => {
+                let handle = Handle::new(p);
+                let ret = handle.read(buf);
+                handle.into_raw();
+                return ret
+            }
         };
         let mut utf8 = self.utf8.lock().unwrap();
         // Read more if the buffer is empty
@@ -125,11 +128,9 @@ impl Stdin {
                 Ok(utf8) => utf8.into_bytes(),
                 Err(..) => return Err(invalid_encoding()),
             };
-            if let Output::Console(_) = self.handle {
-                if let Some(&last_byte) = data.last() {
-                    if last_byte == CTRL_Z {
-                        data.pop();
-                    }
+            if let Some(&last_byte) = data.last() {
+                if last_byte == CTRL_Z {
+                    data.pop();
                 }
             }
             *utf8 = Cursor::new(data);
@@ -158,11 +159,11 @@ impl<'a> Read for &'a Stdin {
 
 impl Stdout {
     pub fn new() -> io::Result<Stdout> {
-        get(c::STD_OUTPUT_HANDLE).map(Stdout)
+        Ok(Stdout)
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        write(&self.0, data)
+        write(c::STD_OUTPUT_HANDLE, data)
     }
 
     pub fn flush(&self) -> io::Result<()> {
@@ -172,11 +173,11 @@ impl Stdout {
 
 impl Stderr {
     pub fn new() -> io::Result<Stderr> {
-        get(c::STD_ERROR_HANDLE).map(Stderr)
+        Ok(Stderr)
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        write(&self.0, data)
+        write(c::STD_ERROR_HANDLE, data)
     }
 
     pub fn flush(&self) -> io::Result<()> {
@@ -197,27 +198,12 @@ impl io::Write for Stderr {
     }
 }
 
-impl NoClose {
-    fn new(handle: c::HANDLE) -> NoClose {
-        NoClose(Some(Handle::new(handle)))
-    }
-
-    fn get(&self) -> &Handle { self.0.as_ref().unwrap() }
-}
-
-impl Drop for NoClose {
-    fn drop(&mut self) {
-        self.0.take().unwrap().into_raw();
-    }
-}
-
 impl Output {
-    pub fn handle(&self) -> &Handle {
-        let nc = match *self {
-            Output::Console(ref c) => c,
-            Output::Pipe(ref c) => c,
-        };
-        nc.0.as_ref().unwrap()
+    pub fn handle(&self) -> c::HANDLE {
+        match *self {
+            Output::Console(c) => c,
+            Output::Pipe(c) => c,
+        }
     }
 }
 
diff --git a/src/libstd/sys/windows/thread_local.rs b/src/libstd/sys/windows/thread_local.rs
index 597f05622a5..ad57f87dc1f 100644
--- a/src/libstd/sys/windows/thread_local.rs
+++ b/src/libstd/sys/windows/thread_local.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use mem;
 use ptr;
+use sync::atomic::AtomicPtr;
+use sync::atomic::Ordering::SeqCst;
 use sys::c;
-use sys_common::mutex::Mutex;
-use sys_common;
 
 pub type Key = c::DWORD;
 pub type Dtor = unsafe extern fn(*mut u8);
@@ -34,8 +35,6 @@ pub type Dtor = unsafe extern fn(*mut u8);
 // * All TLS destructors are tracked by *us*, not the windows runtime. This
 //   means that we have a global list of destructors for each TLS key that
 //   we know about.
-// * When a TLS key is destroyed, we're sure to remove it from the dtor list
-//   if it's in there.
 // * When a thread exits, we run over the entire list and run dtors for all
 //   non-null keys. This attempts to match Unix semantics in this regard.
 //
@@ -50,13 +49,6 @@ pub type Dtor = unsafe extern fn(*mut u8);
 // [2]: https://github.com/ChromiumWebApps/chromium/blob/master/base
 //                        /threading/thread_local_storage_win.cc#L42
 
-// NB these are specifically not types from `std::sync` as they currently rely
-// on poisoning and this module needs to operate at a lower level than requiring
-// the thread infrastructure to be in place (useful on the borders of
-// initialization/destruction).
-static DTOR_LOCK: Mutex = Mutex::new();
-static mut DTORS: *mut Vec<(Key, Dtor)> = ptr::null_mut();
-
 // -------------------------------------------------------------------------
 // Native bindings
 //
@@ -85,81 +77,64 @@ pub unsafe fn get(key: Key) -> *mut u8 {
 }
 
 #[inline]
-pub unsafe fn destroy(key: Key) {
-    if unregister_dtor(key) {
-        // FIXME: Currently if a key has a destructor associated with it we
-        // can't actually ever unregister it. If we were to
-        // unregister it, then any key destruction would have to be
-        // serialized with respect to actually running destructors.
-        //
-        // We want to avoid a race where right before run_dtors runs
-        // some destructors TlsFree is called. Allowing the call to
-        // TlsFree would imply that the caller understands that *all
-        // known threads* are not exiting, which is quite a difficult
-        // thing to know!
-        //
-        // For now we just leak all keys with dtors to "fix" this.
-        // Note that source [2] above shows precedent for this sort
-        // of strategy.
-    } else {
-        let r = c::TlsFree(key);
-        debug_assert!(r != 0);
-    }
+pub unsafe fn destroy(_key: Key) {
+    rtabort!("can't destroy tls keys on windows")
+}
+
+#[inline]
+pub fn requires_synchronized_create() -> bool {
+    true
 }
 
 // -------------------------------------------------------------------------
 // Dtor registration
 //
-// These functions are associated with registering and unregistering
-// destructors. They're pretty simple, they just push onto a vector and scan
-// a vector currently.
+// Windows has no native support for running destructors so we manage our own
+// list of destructors to keep track of how to destroy keys. We then install a
+// callback later to get invoked whenever a thread exits, running all
+// appropriate destructors.
 //
-// FIXME: This could probably be at least a little faster with a BTree.
-
-unsafe fn init_dtors() {
-    if !DTORS.is_null() { return }
+// Currently unregistration from this list is not supported. A destructor can be
+// registered but cannot be unregistered. There's various simplifying reasons
+// for doing this, the big ones being:
+//
+// 1. Currently we don't even support deallocating TLS keys, so normal operation
+//    doesn't need to deallocate a destructor.
+// 2. There is no point in time where we know we can unregister a destructor
+//    because it could always be getting run by some remote thread.
+//
+// Typically processes have a statically known set of TLS keys which is pretty
+// small, and we'd want to keep this memory alive for the whole process anyway
+// really.
+//
+// Perhaps one day we can fold the `Box` here into a static allocation,
+// expanding the `StaticKey` structure to contain not only a slot for the TLS
+// key but also a slot for the destructor queue on windows. An optimization for
+// another day!
 
-    let dtors = box Vec::<(Key, Dtor)>::new();
+static DTORS: AtomicPtr<Node> = AtomicPtr::new(ptr::null_mut());
 
-    let res = sys_common::at_exit(move|| {
-        DTOR_LOCK.lock();
-        let dtors = DTORS;
-        DTORS = 1 as *mut _;
-        Box::from_raw(dtors);
-        assert!(DTORS as usize == 1); // can't re-init after destructing
-        DTOR_LOCK.unlock();
-    });
-    if res.is_ok() {
-        DTORS = Box::into_raw(dtors);
-    } else {
-        DTORS = 1 as *mut _;
-    }
+struct Node {
+    dtor: Dtor,
+    key: Key,
+    next: *mut Node,
 }
 
 unsafe fn register_dtor(key: Key, dtor: Dtor) {
-    DTOR_LOCK.lock();
-    init_dtors();
-    assert!(DTORS as usize != 0);
-    assert!(DTORS as usize != 1,
-            "cannot create new TLS keys after the main thread has exited");
-    (*DTORS).push((key, dtor));
-    DTOR_LOCK.unlock();
-}
+    let mut node = Box::new(Node {
+        key: key,
+        dtor: dtor,
+        next: ptr::null_mut(),
+    });
 
-unsafe fn unregister_dtor(key: Key) -> bool {
-    DTOR_LOCK.lock();
-    init_dtors();
-    assert!(DTORS as usize != 0);
-    assert!(DTORS as usize != 1,
-            "cannot unregister destructors after the main thread has exited");
-    let ret = {
-        let dtors = &mut *DTORS;
-        let before = dtors.len();
-        dtors.retain(|&(k, _)| k != key);
-        dtors.len() != before
-    };
-    DTOR_LOCK.unlock();
-    ret
+    let mut head = DTORS.load(SeqCst);
+    loop {
+        node.next = head;
+        match DTORS.compare_exchange(head, &mut *node, SeqCst, SeqCst) {
+            Ok(_) => return mem::forget(node),
+            Err(cur) => head = cur,
+        }
+    }
 }
 
 // -------------------------------------------------------------------------
@@ -196,16 +171,12 @@ unsafe fn unregister_dtor(key: Key) -> bool {
 // # Ok, what's up with running all these destructors?
 //
 // This will likely need to be improved over time, but this function
-// attempts a "poor man's" destructor callback system. To do this we clone a
-// local copy of the dtor list to start out with. This is our fudgy attempt
-// to not hold the lock while destructors run and not worry about the list
-// changing while we're looking at it.
-//
-// Once we've got a list of what to run, we iterate over all keys, check
-// their values, and then run destructors if the values turn out to be non
-// null (setting them to null just beforehand). We do this a few times in a
-// loop to basically match Unix semantics. If we don't reach a fixed point
-// after a short while then we just inevitably leak something most likely.
+// attempts a "poor man's" destructor callback system. Once we've got a list
+// of what to run, we iterate over all keys, check their values, and then run
+// destructors if the values turn out to be non null (setting them to null just
+// beforehand). We do this a few times in a loop to basically match Unix
+// semantics. If we don't reach a fixed point after a short while then we just
+// inevitably leak something most likely.
 //
 // # The article mentions weird stuff about "/INCLUDE"?
 //
@@ -259,25 +230,21 @@ unsafe extern "system" fn on_tls_callback(h: c::LPVOID,
 unsafe fn run_dtors() {
     let mut any_run = true;
     for _ in 0..5 {
-        if !any_run { break }
+        if !any_run {
+            break
+        }
         any_run = false;
-        let dtors = {
-            DTOR_LOCK.lock();
-            let ret = if DTORS as usize <= 1 {
-                Vec::new()
-            } else {
-                (*DTORS).iter().map(|s| *s).collect()
-            };
-            DTOR_LOCK.unlock();
-            ret
-        };
-        for &(key, dtor) in &dtors {
-            let ptr = c::TlsGetValue(key);
+        let mut cur = DTORS.load(SeqCst);
+        while !cur.is_null() {
+            let ptr = c::TlsGetValue((*cur).key);
+
             if !ptr.is_null() {
-                c::TlsSetValue(key, ptr::null_mut());
-                dtor(ptr as *mut _);
+                c::TlsSetValue((*cur).key, ptr::null_mut());
+                ((*cur).dtor)(ptr as *mut _);
                 any_run = true;
             }
+
+            cur = (*cur).next;
         }
     }
 }
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 99297b781e4..617218fe7a5 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -19,7 +19,7 @@ use io;
 use libc;
 use str;
 use sync::atomic::{self, Ordering};
-use path::Path;
+use path::{self, Path};
 use sys::mutex::Mutex;
 use ptr;
 
@@ -93,6 +93,8 @@ fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
     Ok(())
 }
 
+/// Returns a number of frames to remove at the beginning and at the end of the
+/// backtrace, according to the backtrace format.
 fn filter_frames(frames: &[Frame],
                  format: PrintFormat,
                  context: &BacktraceContext) -> (usize, usize)
@@ -101,74 +103,23 @@ fn filter_frames(frames: &[Frame],
         return (0, 0);
     }
 
-    // We want to filter out frames with some prefixes
-    // from both top and bottom of the call stack.
-    static BAD_PREFIXES_TOP: &'static [&'static str] = &[
-        "_ZN3std3sys3imp9backtrace",
-        "ZN3std3sys3imp9backtrace",
-        "std::sys::imp::backtrace",
-        "_ZN3std10sys_common9backtrace",
-        "ZN3std10sys_common9backtrace",
-        "std::sys_common::backtrace",
-        "_ZN3std9panicking",
-        "ZN3std9panicking",
-        "std::panicking",
-        "_ZN4core9panicking",
-        "ZN4core9panicking",
-        "core::panicking",
-        "_ZN4core6result13unwrap_failed",
-        "ZN4core6result13unwrap_failed",
-        "core::result::unwrap_failed",
-        "rust_begin_unwind",
-        "_ZN4drop",
-        "mingw_set_invalid_parameter_handler",
-    ];
-    static BAD_PREFIXES_BOTTOM: &'static [&'static str] = &[
-        "_ZN3std9panicking",
-        "ZN3std9panicking",
-        "std::panicking",
-        "_ZN3std5panic",
-        "ZN3std5panic",
-        "std::panic",
-        "_ZN4core9panicking",
-        "ZN4core9panicking",
-        "core::panicking",
-        "_ZN3std2rt10lang_start",
-        "ZN3std2rt10lang_start",
-        "std::rt::lang_start",
-        "panic_unwind::__rust_maybe_catch_panic",
-        "__rust_maybe_catch_panic",
-        "_rust_maybe_catch_panic",
-        "__libc_start_main",
-        "__rust_try",
-        "_start",
-        "main",
-        "BaseThreadInitThunk",
-        "RtlInitializeExceptionChain",
-        "__scrt_common_main_seh",
-        "_ZN4drop",
-        "mingw_set_invalid_parameter_handler",
-    ];
-
-    let is_good_frame = |frame: Frame, bad_prefixes: &[&str]| {
-        resolve_symname(frame, |symname| {
+    let skipped_before = 0;
+
+    let skipped_after = frames.len() - frames.iter().position(|frame| {
+        let mut is_marker = false;
+        let _ = resolve_symname(*frame, |symname| {
             if let Some(mangled_symbol_name) = symname {
-                if !bad_prefixes.iter().any(|s| mangled_symbol_name.starts_with(s)) {
-                    return Ok(())
+                // Use grep to find the concerned functions
+                if mangled_symbol_name.contains("__rust_begin_short_backtrace") {
+                    is_marker = true;
                 }
             }
-            Err(io::Error::from(io::ErrorKind::Other))
-        }, context).is_ok()
-    };
-
-    let skipped_before = frames.iter().position(|frame| {
-        is_good_frame(*frame, BAD_PREFIXES_TOP)
+            Ok(())
+        }, context);
+        is_marker
     }).unwrap_or(frames.len());
-    let skipped_after = frames[skipped_before..].iter().rev().position(|frame| {
-        is_good_frame(*frame, BAD_PREFIXES_BOTTOM)
-    }).unwrap_or(frames.len() - skipped_before);
 
-    if skipped_before + skipped_after == frames.len() {
+    if skipped_before + skipped_after >= frames.len() {
         // Avoid showing completely empty backtraces
         return (0, 0);
     }
@@ -176,6 +127,15 @@ fn filter_frames(frames: &[Frame],
     (skipped_before, skipped_after)
 }
 
+
+/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`.
+#[inline(never)]
+pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
+    where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+{
+    f()
+}
+
 /// Controls how the backtrace should be formated.
 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
 pub enum PrintFormat {
@@ -262,7 +222,7 @@ fn output_fileline(w: &mut Write, file: &[u8], line: libc::c_int,
         if let Ok(cwd) = env::current_dir() {
             if let Ok(stripped) = file_path.strip_prefix(&cwd) {
                 if let Some(s) = stripped.to_str() {
-                    write!(w, "  at ./{}:{}", s, line)?;
+                    write!(w, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
                     already_printed = true;
                 }
             }
diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs
index 3cdeb511945..a1897c8bd67 100644
--- a/src/libstd/sys_common/net.rs
+++ b/src/libstd/sys_common/net.rs
@@ -177,9 +177,22 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
     };
     let mut res = ptr::null_mut();
     unsafe {
-        cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints,
-                               &mut res))?;
-        Ok(LookupHost { original: res, cur: res })
+        match cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) {
+            Ok(_) => {
+                Ok(LookupHost { original: res, cur: res })
+            },
+            #[cfg(unix)]
+            Err(e) => {
+                // The lookup failure could be caused by using a stale /etc/resolv.conf.
+                // See https://github.com/rust-lang/rust/issues/41570.
+                // We therefore force a reload of the nameserver information.
+                c::res_init();
+                Err(e)
+            },
+            // the cfg is needed here to avoid an "unreachable pattern" warning
+            #[cfg(not(unix))]
+            Err(e) => Err(e),
+        }
     }
 }
 
@@ -339,7 +352,7 @@ impl TcpListener {
 
         // Bind our new socket
         let (addrp, len) = addr.into_inner();
-        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
+        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
 
         // Start listening
         cvt(unsafe { c::listen(*sock.as_inner(), 128) })?;
@@ -430,7 +443,7 @@ impl UdpSocket {
 
         let sock = Socket::new(addr, c::SOCK_DGRAM)?;
         let (addrp, len) = addr.into_inner();
-        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
+        cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
         Ok(UdpSocket { inner: sock })
     }
 
diff --git a/src/libstd/sys_common/poison.rs b/src/libstd/sys_common/poison.rs
index d9d13240fcc..0127a9eb759 100644
--- a/src/libstd/sys_common/poison.rs
+++ b/src/libstd/sys_common/poison.rs
@@ -73,7 +73,9 @@ pub struct PoisonError<T> {
 }
 
 /// An enumeration of possible errors which can occur while calling the
-/// `try_lock` method.
+/// [`try_lock`] method.
+///
+/// [`try_lock`]: struct.Mutex.html#method.try_lock
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum TryLockError<T> {
     /// The lock could not be acquired because another thread failed while holding
diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs
index 95d8b6cc951..5ed48ee4558 100644
--- a/src/libstd/sys_common/thread_info.rs
+++ b/src/libstd/sys_common/thread_info.rs
@@ -31,7 +31,7 @@ impl ThreadInfo {
             if c.borrow().is_none() {
                 *c.borrow_mut() = Some(ThreadInfo {
                     stack_guard: None,
-                    thread: NewThread::new(None),
+                    thread: Thread::new(None),
                 })
             }
             Some(f(c.borrow_mut().as_mut().unwrap()))
@@ -54,8 +54,3 @@ pub fn set(stack_guard: Option<usize>, thread: Thread) {
         thread: thread,
     }));
 }
-
-// a hack to get around privacy restrictions; implemented by `std::thread`
-pub trait NewThread {
-    fn new(name: Option<String>) -> Self;
-}
diff --git a/src/libstd/sys_common/thread_local.rs b/src/libstd/sys_common/thread_local.rs
index 25a9d5720d9..0ade90e64c3 100644
--- a/src/libstd/sys_common/thread_local.rs
+++ b/src/libstd/sys_common/thread_local.rs
@@ -61,6 +61,7 @@
 use sync::atomic::{self, AtomicUsize, Ordering};
 
 use sys::thread_local as imp;
+use sys_common::mutex::Mutex;
 
 /// A type for TLS keys that are statically allocated.
 ///
@@ -145,20 +146,6 @@ impl StaticKey {
     #[inline]
     pub unsafe fn set(&self, val: *mut u8) { imp::set(self.key(), val) }
 
-    /// Deallocates this OS TLS key.
-    ///
-    /// This function is unsafe as there is no guarantee that the key is not
-    /// currently in use by other threads or will not ever be used again.
-    ///
-    /// Note that this does *not* run the user-provided destructor if one was
-    /// specified at definition time. Doing so must be done manually.
-    pub unsafe fn destroy(&self) {
-        match self.key.swap(0, Ordering::SeqCst) {
-            0 => {}
-            n => { imp::destroy(n as imp::Key) }
-        }
-    }
-
     #[inline]
     unsafe fn key(&self) -> imp::Key {
         match self.key.load(Ordering::Relaxed) {
@@ -168,6 +155,24 @@ impl StaticKey {
     }
 
     unsafe fn lazy_init(&self) -> usize {
+        // Currently the Windows implementation of TLS is pretty hairy, and
+        // it greatly simplifies creation if we just synchronize everything.
+        //
+        // Additionally a 0-index of a tls key hasn't been seen on windows, so
+        // we just simplify the whole branch.
+        if imp::requires_synchronized_create() {
+            static INIT_LOCK: Mutex = Mutex::new();
+            INIT_LOCK.lock();
+            let mut key = self.key.load(Ordering::SeqCst);
+            if key == 0 {
+                key = imp::create(self.dtor) as usize;
+                self.key.store(key, Ordering::SeqCst);
+            }
+            INIT_LOCK.unlock();
+            assert!(key != 0);
+            return key
+        }
+
         // POSIX allows the key created here to be 0, but the compare_and_swap
         // below relies on using 0 as a sentinel value to check who won the
         // race to set the shared TLS key. As far as I know, there is no
@@ -227,7 +232,9 @@ impl Key {
 
 impl Drop for Key {
     fn drop(&mut self) {
-        unsafe { imp::destroy(self.key) }
+        // Right now Windows doesn't support TLS key destruction, but this also
+        // isn't used anywhere other than tests, so just leak the TLS key.
+        // unsafe { imp::destroy(self.key) }
     }
 }
 
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index b486d4ffda3..df5e4ef1d88 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -351,6 +351,12 @@ impl Wtf8Buf {
     pub fn into_box(self) -> Box<Wtf8> {
         unsafe { mem::transmute(self.bytes.into_boxed_slice()) }
     }
+
+    /// Converts a `Box<Wtf8>` into a `Wtf8Buf`.
+    pub fn from_box(boxed: Box<Wtf8>) -> Wtf8Buf {
+        let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) };
+        Wtf8Buf { bytes: bytes.into_vec() }
+    }
 }
 
 /// Create a new WTF-8 string from an iterator of code points.
@@ -744,6 +750,7 @@ impl<'a> Iterator for Wtf8CodePoints<'a> {
     }
 }
 
+/// Generates a wide character sequence for potentially ill-formed UTF-16.
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Clone)]
 pub struct EncodeWide<'a> {
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 66f09a7069c..c2c6e6cf87d 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -19,16 +19,16 @@ use mem;
 /// A thread local storage key which owns its contents.
 ///
 /// This key uses the fastest possible implementation available to it for the
-/// target platform. It is instantiated with the `thread_local!` macro and the
-/// primary method is the `with` method.
+/// target platform. It is instantiated with the [`thread_local!`] macro and the
+/// primary method is the [`with`] method.
 ///
-/// The `with` method yields a reference to the contained value which cannot be
+/// The [`with`] method yields a reference to the contained value which cannot be
 /// sent across threads or escape the given closure.
 ///
 /// # Initialization and Destruction
 ///
-/// Initialization is dynamically performed on the first call to `with()`
-/// within a thread, and values that implement `Drop` get destructed when a
+/// Initialization is dynamically performed on the first call to [`with`]
+/// within a thread, and values that implement [`Drop`] get destructed when a
 /// thread exits. Some caveats apply, which are explained below.
 ///
 /// # Examples
@@ -74,9 +74,13 @@ use mem;
 ///    destroyed, but not all platforms have this guard. Those platforms that do
 ///    not guard typically have a synthetic limit after which point no more
 ///    destructors are run.
-/// 3. On OSX, initializing TLS during destruction of other TLS slots can
+/// 3. On macOS, initializing TLS during destruction of other TLS slots can
 ///    sometimes cancel *all* destructors for the current thread, whether or not
 ///    the slots have already had their destructors run or not.
+///
+/// [`with`]: ../../std/thread/struct.LocalKey.html#method.with
+/// [`thread_local!`]: ../../std/macro.thread_local.html
+/// [`Drop`]: ../../std/ops/trait.Drop.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct LocalKey<T: 'static> {
     // This outer `LocalKey<T>` type is what's going to be stored in statics,
@@ -106,7 +110,7 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
     }
 }
 
-/// Declare a new thread local storage key of type `std::thread::LocalKey`.
+/// Declare a new thread local storage key of type [`std::thread::LocalKey`].
 ///
 /// # Syntax
 ///
@@ -124,8 +128,10 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
 /// # fn main() {}
 /// ```
 ///
-/// See [LocalKey documentation](thread/struct.LocalKey.html) for more
+/// See [LocalKey documentation][`std::thread::LocalKey`] for more
 /// information.
+///
+/// [`std::thread::LocalKey`]: ../std/thread/struct.LocalKey.html
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[allow_internal_unstable]
@@ -195,11 +201,13 @@ macro_rules! __thread_local_inner {
 #[derive(Debug, Eq, PartialEq, Copy, Clone)]
 pub enum LocalKeyState {
     /// All keys are in this state whenever a thread starts. Keys will
-    /// transition to the `Valid` state once the first call to `with` happens
+    /// transition to the `Valid` state once the first call to [`with`] happens
     /// and the initialization expression succeeds.
     ///
     /// Keys in the `Uninitialized` state will yield a reference to the closure
-    /// passed to `with` so long as the initialization routine does not panic.
+    /// passed to [`with`] so long as the initialization routine does not panic.
+    ///
+    /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with
     Uninitialized,
 
     /// Once a key has been accessed successfully, it will enter the `Valid`
@@ -208,7 +216,9 @@ pub enum LocalKeyState {
     /// `Destroyed` state.
     ///
     /// Keys in the `Valid` state will be guaranteed to yield a reference to the
-    /// closure passed to `with`.
+    /// closure passed to [`with`].
+    ///
+    /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with
     Valid,
 
     /// When a thread exits, the destructors for keys will be run (if
@@ -216,7 +226,9 @@ pub enum LocalKeyState {
     /// destructor has run, a key is in the `Destroyed` state.
     ///
     /// Keys in the `Destroyed` states will trigger a panic when accessed via
-    /// `with`.
+    /// [`with`].
+    ///
+    /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with
     Destroyed,
 }
 
@@ -283,23 +295,26 @@ impl<T: 'static> LocalKey<T> {
     /// Query the current state of this key.
     ///
     /// A key is initially in the `Uninitialized` state whenever a thread
-    /// starts. It will remain in this state up until the first call to `with`
+    /// starts. It will remain in this state up until the first call to [`with`]
     /// within a thread has run the initialization expression successfully.
     ///
     /// Once the initialization expression succeeds, the key transitions to the
-    /// `Valid` state which will guarantee that future calls to `with` will
+    /// `Valid` state which will guarantee that future calls to [`with`] will
     /// succeed within the thread.
     ///
     /// When a thread exits, each key will be destroyed in turn, and as keys are
     /// destroyed they will enter the `Destroyed` state just before the
     /// destructor starts to run. Keys may remain in the `Destroyed` state after
     /// destruction has completed. Keys without destructors (e.g. with types
-    /// that are `Copy`), may never enter the `Destroyed` state.
+    /// that are [`Copy`]), may never enter the `Destroyed` state.
     ///
     /// Keys in the `Uninitialized` state can be accessed so long as the
     /// initialization does not panic. Keys in the `Valid` state are guaranteed
     /// to be able to be accessed. Keys in the `Destroyed` state will panic on
-    /// any call to `with`.
+    /// any call to [`with`].
+    ///
+    /// [`with`]: ../../std/thread/struct.LocalKey.html#method.with
+    /// [`Copy`]: ../../std/marker/trait.Copy.html
     #[unstable(feature = "thread_local_state",
                reason = "state querying was recently added",
                issue = "27716")]
@@ -524,9 +539,9 @@ mod tests {
     }
 
     // Note that this test will deadlock if TLS destructors aren't run (this
-    // requires the destructor to be run to pass the test). OSX has a known bug
+    // requires the destructor to be run to pass the test). macOS has a known bug
     // where dtors-in-dtors may cancel other destructors, so we just ignore this
-    // test on OSX.
+    // test on macOS.
     #[test]
     #[cfg_attr(target_os = "macos", ignore)]
     fn dtors_in_dtors_in_dtors() {
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 2bc066d3fea..d0e3b00d75f 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -66,7 +66,7 @@
 //! let res = child.join();
 //! ```
 //!
-//! The [`join`] method returns a [`Result`] containing [`Ok`] of the final
+//! The [`join`] method returns a [`thread::Result`] containing [`Ok`] of the final
 //! value produced by the child thread, or [`Err`] of the value given to
 //! a call to [`panic!`] if the child panicked.
 //!
@@ -90,47 +90,12 @@
 //! two ways:
 //!
 //! * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
-//!   function, and calling [`thread()`] on the [`JoinHandle`].
-//! * By requesting the current thread, using the [`thread::current()`] function.
+//!   function, and calling [`thread`][`JoinHandle::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
+//! 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
-//! [`thread::park()`][`park()`] function and [`thread::Thread::unpark()`][`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:
-//!
-//! * The [`thread::park()`][`park()`] function blocks the current thread unless or until
-//!   the token is available for its thread handle, at which point it atomically
-//!   consumes the token. It may also return *spuriously*, without consuming the
-//!   token. [`thread::park_timeout()`] does the same, but allows specifying a
-//!   maximum time to block the thread for.
-//!
-//! * The [`unpark()`] method on a [`Thread`] atomically makes the token available
-//!   if it wasn't already.
-//!
-//! In other words, each [`Thread`] acts a bit like a semaphore with initial count
-//! 0, except that the semaphore is *saturating* (the count cannot go above 1),
-//! and can return spuriously.
-//!
-//! The API is typically used by acquiring a handle to the current thread,
-//! placing that handle in a shared data structure so that other threads can
-//! find it, and then `park`ing. When some desired condition is met, another
-//! thread calls [`unpark()`] on the handle.
-//!
-//! The motivation for this design is twofold:
-//!
-//! * It avoids the need to allocate mutexes and condvars when building new
-//!   synchronization primitives; the threads already provide basic blocking/signaling.
-//!
-//! * It can be implemented very efficiently on many platforms.
-//!
 //! ## Thread-local storage
 //!
 //! This module also provides an implementation of thread-local storage for Rust
@@ -151,18 +116,19 @@
 //! [`Arc`]: ../../std/sync/struct.Arc.html
 //! [`spawn`]: ../../std/thread/fn.spawn.html
 //! [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
-//! [`thread()`]: ../../std/thread/struct.JoinHandle.html#method.thread
+//! [`JoinHandle::thread`]: ../../std/thread/struct.JoinHandle.html#method.thread
 //! [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
 //! [`Result`]: ../../std/result/enum.Result.html
 //! [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
 //! [`Err`]: ../../std/result/enum.Result.html#variant.Err
 //! [`panic!`]: ../../std/macro.panic.html
 //! [`Builder`]: ../../std/thread/struct.Builder.html
-//! [`thread::current()`]: ../../std/thread/fn.spawn.html
+//! [`thread::current`]: ../../std/thread/fn.current.html
+//! [`thread::Result`]: ../../std/thread/type.Result.html
 //! [`Thread`]: ../../std/thread/struct.Thread.html
-//! [`park()`]: ../../std/thread/fn.park.html
-//! [`unpark()`]: ../../std/thread/struct.Thread.html#method.unpark
-//! [`thread::park_timeout()`]: ../../std/thread/fn.park_timeout.html
+//! [`park`]: ../../std/thread/fn.park.html
+//! [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
+//! [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
 //! [`Cell`]: ../cell/struct.Cell.html
 //! [`RefCell`]: ../cell/struct.RefCell.html
 //! [`thread_local!`]: ../macro.thread_local.html
@@ -214,8 +180,33 @@ pub use self::local::{LocalKey, LocalKeyState};
 // Builder
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Thread configuration. Provides detailed control over the properties
-/// and behavior of new threads.
+/// Thread factory, which can be used in order to configure the properties of
+/// a new thread.
+///
+/// Methods can be chained on it in order to configure it.
+///
+/// The two configurations available are:
+///
+/// - [`name`]: allows to give a name to the thread which is currently
+///   only used in `panic` messages.
+/// - [`stack_size`]: specifies the desired stack size. Note that this can
+///   be overriden by the OS.
+///
+/// If the [`stack_size`] field is not specified, the stack size
+/// will be the `RUST_MIN_STACK` environment variable. If it is
+/// not specified either, a sensible default will be set.
+///
+/// If the [`name`] field is not specified, the thread will not be named.
+///
+/// The [`spawn`] method will take ownership of the builder and create an
+/// [`io::Result`] to the thread handle with the given configuration.
+///
+/// The [`thread::spawn`] free function uses a `Builder` with default
+/// configuration and [`unwrap`]s its return value.
+///
+/// You may want to use [`spawn`] instead of [`thread::spawn`], when you want
+/// to recover from a failure to launch a thread, indeed the free function will
+/// panick where the `Builder` method will return a [`io::Result`].
 ///
 /// # Examples
 ///
@@ -230,6 +221,13 @@ pub use self::local::{LocalKey, LocalKeyState};
 ///
 /// handler.join().unwrap();
 /// ```
+///
+/// [`thread::spawn`]: ../../std/thread/fn.spawn.html
+/// [`stack_size`]: ../../std/thread/struct.Builder.html#method.stack_size
+/// [`name`]: ../../std/thread/struct.Builder.html#method.name
+/// [`spawn`]: ../../std/thread/struct.Builder.html#method.spawn
+/// [`io::Result`]: ../../std/io/type.Result.html
+/// [`unwrap`]: ../../std/result/enum.Result.html#method.unwrap
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Builder {
@@ -307,13 +305,16 @@ impl Builder {
         self
     }
 
-    /// Spawns a new thread, and returns a join handle for it.
+    /// Spawns a new thread by taking ownership of the `Builder`, and returns an
+    /// [`io::Result`] to its [`JoinHandle`].
     ///
-    /// The child thread may outlive the parent (unless the parent thread
+    /// The spawned thread may outlive the caller (unless the caller thread
     /// is the main thread; the whole process is terminated when the main
     /// thread finishes). The join handle can be used to block on
     /// termination of the child thread, including recovering its panics.
     ///
+    /// For a more complete documentation see [`thread::spawn`][`spawn`].
+    ///
     /// # Errors
     ///
     /// Unlike the [`spawn`] free function, this method yields an
@@ -322,6 +323,7 @@ impl Builder {
     ///
     /// [`spawn`]: ../../std/thread/fn.spawn.html
     /// [`io::Result`]: ../../std/io/type.Result.html
+    /// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
     ///
     /// # Examples
     ///
@@ -357,6 +359,11 @@ impl Builder {
             }
             unsafe {
                 thread_info::set(imp::guard::current(), their_thread);
+                #[cfg(feature = "backtrace")]
+                let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
+                    ::sys_common::backtrace::__rust_begin_short_backtrace(f)
+                }));
+                #[cfg(not(feature = "backtrace"))]
                 let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
                 *their_packet.get() = Some(try_result);
             }
@@ -386,19 +393,39 @@ impl Builder {
 /// panics, [`join`] will return an [`Err`] containing the argument given to
 /// [`panic`].
 ///
+/// This will create a thread using default parameters of [`Builder`], if you
+/// want to specify the stack size or the name of the thread, use this API
+/// instead.
+///
+/// As you can see in the signature of `spawn` there are two constraints on
+/// both the closure given to `spawn` and its return value, let's explain them:
+///
+/// - The `'static` constraint means that the closure and its return value
+///   must have a lifetime of the whole program execution. The reason for this
+///   is that threads can `detach` and outlive the lifetime they have been
+///   created in.
+///   Indeed if the thread, and by extension its return value, can outlive their
+///   caller, we need to make sure that they will be valid afterwards, and since
+///   we *can't* know when it will return we need to have them valid as long as
+///   possible, that is until the end of the program, hence the `'static`
+///   lifetime.
+/// - The [`Send`] constraint is because the closure will need to be passed
+///   *by value* from the thread where it is spawned to the new thread. Its
+///   return value will need to be passed from the new thread to the thread
+///   where it is `join`ed.
+///   As a reminder, the [`Send`] marker trait, expresses that it is safe to be
+///   passed from thread to thread. [`Sync`] expresses that it is safe to have a
+///   reference be passed from thread to thread.
+///
 /// # Panics
 ///
 /// Panics if the OS fails to create a thread; use [`Builder::spawn`]
 /// to recover from such errors.
 ///
-/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
-/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
-/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
-/// [`panic`]: ../../std/macro.panic.html
-/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
-///
 /// # Examples
 ///
+/// Creating a thread.
+///
 /// ```
 /// use std::thread;
 ///
@@ -408,6 +435,56 @@ impl Builder {
 ///
 /// handler.join().unwrap();
 /// ```
+///
+/// As mentioned in the module documentation, threads are usually made to
+/// communicate using [`channels`], here is how it usually looks.
+///
+/// This example also shows how to use `move`, in order to give ownership
+/// of values to a thread.
+///
+/// ```
+/// use std::thread;
+/// use std::sync::mpsc::channel;
+///
+/// let (tx, rx) = channel();
+///
+/// let sender = thread::spawn(move || {
+///     let _ = tx.send("Hello, thread".to_owned());
+/// });
+///
+/// let receiver = thread::spawn(move || {
+///     println!("{}", rx.recv().unwrap());
+/// });
+///
+/// let _ = sender.join();
+/// let _ = receiver.join();
+/// ```
+///
+/// A thread can also return a value through its [`JoinHandle`], you can use
+/// this to make asynchronous computations (futures might be more appropriate
+/// though).
+///
+/// ```
+/// use std::thread;
+///
+/// let computation = thread::spawn(|| {
+///     // Some expensive computation.
+///     42
+/// });
+///
+/// let result = computation.join().unwrap();
+/// println!("{}", result);
+/// ```
+///
+/// [`channels`]: ../../std/sync/mpsc/index.html
+/// [`JoinHandle`]: ../../std/thread/struct.JoinHandle.html
+/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
+/// [`Err`]: ../../std/result/enum.Result.html#variant.Err
+/// [`panic`]: ../../std/macro.panic.html
+/// [`Builder::spawn`]: ../../std/thread/struct.Builder.html#method.spawn
+/// [`Builder`]: ../../std/thread/struct.Builder.html
+/// [`Send`]: ../../std/marker/trait.Send.html
+/// [`Sync`]: ../../std/marker/trait.Sync.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn spawn<F, T>(f: F) -> JoinHandle<T> where
     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
@@ -443,6 +520,23 @@ pub fn current() -> Thread {
 
 /// Cooperatively gives up a timeslice to the OS scheduler.
 ///
+/// This is used when the programmer knows that the thread will have nothing
+/// to do for some time, and thus avoid wasting computing time.
+///
+/// For example when polling on a resource, it is common to check that it is
+/// available, and if not to yield in order to avoid busy waiting.
+///
+/// Thus the pattern of `yield`ing after a failed poll is rather common when
+/// implementing low-level shared resources or synchronization primitives.
+///
+/// However programmers will usualy prefer to use, [`channel`]s, [`Condvar`]s,
+/// [`Mutex`]es or [`join`] for their synchronisation routines, as they avoid
+/// thinking about thread schedulling.
+///
+/// Note that [`channel`]s for example are implemented using this primitive.
+/// Indeed when you call `send` or `recv`, which are blocking, they will yield
+/// if the channel is not available.
+///
 /// # Examples
 ///
 /// ```
@@ -450,6 +544,12 @@ pub fn current() -> Thread {
 ///
 /// thread::yield_now();
 /// ```
+///
+/// [`channel`]: ../../std/sync/mpsc/index.html
+/// [`spawn`]: ../../std/thread/fn.spawn.html
+/// [`join`]: ../../std/thread/struct.JoinHandle.html#method.join
+/// [`Mutex`]: ../../std/sync/struct.Mutex.html
+/// [`Condvar`]: ../../std/sync/struct.Condvar.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn yield_now() {
     imp::Thread::yield_now()
@@ -457,6 +557,16 @@ pub fn yield_now() {
 
 /// Determines whether the current thread is unwinding because of panic.
 ///
+/// A common use of this feature is to poison shared resources when writing
+/// unsafe code, by checking `panicking` when the `drop` is called.
+///
+/// This is usually not needed when writing safe code, as [`Mutex`es][Mutex]
+/// already poison themselves when a thread panics while holding the lock.
+///
+/// This can also be used in multithreaded applications, in order to send a
+/// message to other threads warning that a thread has panicked (e.g. for
+/// monitoring purposes).
+///
 /// # Examples
 ///
 /// ```should_panic
@@ -485,6 +595,8 @@ pub fn yield_now() {
 ///     panic!()
 /// }
 /// ```
+///
+/// [Mutex]: ../../std/sync/struct.Mutex.html
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn panicking() -> bool {
@@ -546,23 +658,72 @@ pub fn sleep(dur: Duration) {
 
 /// Blocks unless or until the current thread's token is made available.
 ///
-/// Every thread is equipped with some basic low-level blocking support, via
-/// the `park()` function and the [`unpark()`][unpark] method. These can be
-/// used as a more CPU-efficient implementation of a spinlock.
+/// A call to `park` does not guarantee that the thread will remain parked
+/// forever, and callers should be prepared for this possibility.
+///
+/// # park and unpark
 ///
-/// [unpark]: struct.Thread.html#method.unpark
+/// Every thread is equipped with some basic low-level blocking support, via the
+/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`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:
+///
+/// * The [`thread::park`][`park`] function blocks the current thread unless or
+///   until the token is available for its thread handle, at which point it
+///   atomically consumes the token. It may also return *spuriously*, without
+///   consuming the token. [`thread::park_timeout`] does the same, but allows
+///   specifying a maximum time to block the thread for.
+///
+/// * The [`unpark`] method on a [`Thread`] atomically makes the token available
+///   if it wasn't already.
+///
+/// In other words, each [`Thread`] acts a bit like a spinlock that can be
+/// locked and unlocked using `park` and `unpark`.
 ///
 /// The API is typically used by acquiring a handle to the current thread,
 /// placing that handle in a shared data structure so that other threads can
-/// find it, and then parking (in a loop with a check for the token actually
-/// being acquired).
+/// find it, and then `park`ing. When some desired condition is met, another
+/// thread calls [`unpark`] on the handle.
 ///
-/// A call to `park` does not guarantee that the thread will remain parked
-/// forever, and callers should be prepared for this possibility.
+/// The motivation for this design is twofold:
+///
+/// * It avoids the need to allocate mutexes and condvars when building new
+///   synchronization primitives; the threads already provide basic
+///   blocking/signaling.
+///
+/// * It can be implemented very efficiently on many platforms.
+///
+/// # Examples
+///
+/// ```
+/// use std::thread;
+/// use std::time::Duration;
+///
+/// let parked_thread = thread::Builder::new()
+///     .spawn(|| {
+///         println!("Parking thread");
+///         thread::park();
+///         println!("Thread unparked");
+///     })
+///     .unwrap();
 ///
-/// See the [module documentation][thread] for more detail.
+/// // Let some time pass for the thread to be spawned.
+/// thread::sleep(Duration::from_millis(10));
 ///
-/// [thread]: index.html
+/// println!("Unpark the thread");
+/// parked_thread.thread().unpark();
+///
+/// parked_thread.join().unwrap();
+/// ```
+///
+/// [`Thread`]: ../../std/thread/struct.Thread.html
+/// [`park`]: ../../std/thread/fn.park.html
+/// [`unpark`]: ../../std/thread/struct.Thread.html#method.unpark
+/// [`thread::park_timeout`]: ../../std/thread/fn.park_timeout.html
 //
 // The implementation currently uses the trivial strategy of a Mutex+Condvar
 // with wakeup flag, which does not actually allow spurious wakeups. In the
@@ -579,21 +740,21 @@ pub fn park() {
     *guard = false;
 }
 
-/// Use [park_timeout].
+/// Use [`park_timeout`].
 ///
 /// Blocks unless or until the current thread's token is made available or
 /// 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
-/// should not be used for precise timing due to anomalies such as
+/// The semantics of this function are equivalent to [`park`] except
+/// that the 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 `ms` long.
 ///
-/// See the [module documentation][thread] for more detail.
+/// See the [park documentation][`park`] for more detail.
 ///
-/// [thread]: index.html
-/// [park_timeout]: fn.park_timeout.html
+/// [`park_timeout`]: fn.park_timeout.html
+/// [`park`]: ../../std/thread/fn.park.html
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_deprecated(since = "1.6.0", reason = "replaced by `std::thread::park_timeout`")]
 pub fn park_timeout_ms(ms: u32) {
@@ -603,13 +764,13 @@ pub fn park_timeout_ms(ms: u32) {
 /// Blocks unless or until the current thread's token is made available or
 /// 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
-/// should not be used for precise timing due to anomalies such as
+/// The semantics of this function are equivalent to [`park`][park] except
+/// that the 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.
 ///
-/// See the module doc for more detail.
+/// See the [park dococumentation][park] for more details.
 ///
 /// # Platform behavior
 ///
@@ -634,6 +795,8 @@ pub fn park_timeout_ms(ms: u32) {
 ///     park_timeout(timeout);
 /// }
 /// ```
+///
+/// [park]: fn.park.html
 #[stable(feature = "park_timeout", since = "1.4.0")]
 pub fn park_timeout(dur: Duration) {
     let thread = current();
@@ -652,8 +815,8 @@ pub fn park_timeout(dur: Duration) {
 /// A unique identifier for a running thread.
 ///
 /// A `ThreadId` is an opaque object that has a unique value for each thread
-/// that creates one. `ThreadId`s do not correspond to a thread's system-
-/// designated identifier.
+/// that creates one. `ThreadId`s are not guaranteed to correspond to a thread's
+/// system-designated identifier.
 ///
 /// # Examples
 ///
@@ -662,17 +825,15 @@ pub fn park_timeout(dur: Duration) {
 ///
 /// use std::thread;
 ///
-/// let handler = thread::Builder::new()
-///     .spawn(|| {
-///         let thread = thread::current();
-///         let thread_id = thread.id();
-///     })
-///     .unwrap();
+/// let other_thread = thread::spawn(|| {
+///     thread::current().id()
+/// });
 ///
-/// handler.join().unwrap();
+/// let other_thread_id = other_thread.join().unwrap();
+/// assert!(thread::current().id() != other_thread_id);
 /// ```
 #[unstable(feature = "thread_id", issue = "21507")]
-#[derive(Eq, PartialEq, Copy, Clone)]
+#[derive(Eq, PartialEq, Clone, Copy, Hash, Debug)]
 pub struct ThreadId(u64);
 
 impl ThreadId {
@@ -701,13 +862,6 @@ impl ThreadId {
     }
 }
 
-#[unstable(feature = "thread_id", issue = "21507")]
-impl fmt::Debug for ThreadId {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        f.pad("ThreadId { .. }")
-    }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Thread
 ////////////////////////////////////////////////////////////////////////////////
@@ -724,28 +878,31 @@ struct Inner {
 #[stable(feature = "rust1", since = "1.0.0")]
 /// A handle to a thread.
 ///
-/// # Examples
+/// Threads are represented via the `Thread` type, which you can get in one of
+/// two ways:
 ///
-/// ```
-/// use std::thread;
+/// * By spawning a new thread, e.g. using the [`thread::spawn`][`spawn`]
+///   function, and calling [`thread`][`JoinHandle::thread`] on the
+///   [`JoinHandle`].
+/// * By requesting the current thread, using the [`thread::current`] function.
 ///
-/// let handler = thread::Builder::new()
-///     .name("foo".into())
-///     .spawn(|| {
-///         let thread = thread::current();
-///         println!("thread name: {}", thread.name().unwrap());
-///     })
-///     .unwrap();
+/// The [`thread::current`] function is available even for threads not spawned
+/// by the APIs of this module.
 ///
-/// handler.join().unwrap();
-/// ```
+/// There is usualy no need to create a `Thread` struct yourself, one
+/// should instead use a function like `spawn` to create new threads, see the
+/// docs of [`Builder`] and [`spawn`] for more details.
+///
+/// [`Builder`]: ../../std/thread/struct.Builder.html
+/// [`spawn`]: ../../std/thread/fn.spawn.html
+
 pub struct Thread {
     inner: Arc<Inner>,
 }
 
 impl Thread {
     // Used only internally to construct a thread object without spawning
-    fn new(name: Option<String>) -> Thread {
+    pub(crate) fn new(name: Option<String>) -> Thread {
         let cname = name.map(|n| {
             CString::new(n).expect("thread name may not contain interior null bytes")
         });
@@ -761,22 +918,36 @@ impl Thread {
 
     /// Atomically makes the handle's token available if it is not already.
     ///
-    /// See the module doc for more detail.
+    /// Every thread is equipped with some basic low-level blocking support, via
+    /// the [`park`][park] function and the `unpark()` method. These can be
+    /// used as a more CPU-efficient implementation of a spinlock.
+    ///
+    /// See the [park documentation][park] for more details.
     ///
     /// # Examples
     ///
     /// ```
     /// use std::thread;
+    /// use std::time::Duration;
     ///
-    /// let handler = thread::Builder::new()
+    /// let parked_thread = thread::Builder::new()
     ///     .spawn(|| {
-    ///         let thread = thread::current();
-    ///         thread.unpark();
+    ///         println!("Parking thread");
+    ///         thread::park();
+    ///         println!("Thread unparked");
     ///     })
     ///     .unwrap();
     ///
-    /// handler.join().unwrap();
+    /// // Let some time pass for the thread to be spawned.
+    /// thread::sleep(Duration::from_millis(10));
+    ///
+    /// println!("Unpark the thread");
+    /// parked_thread.thread().unpark();
+    ///
+    /// parked_thread.join().unwrap();
     /// ```
+    ///
+    /// [park]: fn.park.html
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn unpark(&self) {
         let mut guard = self.inner.lock.lock().unwrap();
@@ -795,14 +966,12 @@ impl Thread {
     ///
     /// use std::thread;
     ///
-    /// let handler = thread::Builder::new()
-    ///     .spawn(|| {
-    ///         let thread = thread::current();
-    ///         println!("thread id: {:?}", thread.id());
-    ///     })
-    ///     .unwrap();
+    /// let other_thread = thread::spawn(|| {
+    ///     thread::current().id()
+    /// });
     ///
-    /// handler.join().unwrap();
+    /// let other_thread_id = other_thread.join().unwrap();
+    /// assert!(thread::current().id() != other_thread_id);
     /// ```
     #[unstable(feature = "thread_id", issue = "21507")]
     pub fn id(&self) -> ThreadId {
@@ -858,18 +1027,35 @@ impl fmt::Debug for Thread {
     }
 }
 
-// a hack to get around privacy restrictions
-impl thread_info::NewThread for Thread {
-    fn new(name: Option<String>) -> Thread { Thread::new(name) }
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // JoinHandle
 ////////////////////////////////////////////////////////////////////////////////
 
+/// A specialized [`Result`] type for threads.
+///
 /// Indicates the manner in which a thread exited.
 ///
 /// A thread that completes without panicking is considered to exit successfully.
+///
+/// # Examples
+///
+/// ```no_run
+/// use std::thread;
+/// use std::fs;
+///
+/// fn copy_in_thread() -> thread::Result<()> {
+///     thread::spawn(move || { fs::copy("foo.txt", "bar.txt").unwrap(); }).join()
+/// }
+///
+/// fn main() {
+///     match copy_in_thread() {
+///         Ok(_) => println!("this is fine"),
+///         Err(_) => println!("thread panicked"),
+///     }
+/// }
+/// ```
+///
+/// [`Result`]: ../../std/result/enum.Result.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
 
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index af7eaeb3106..55766ba3fed 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -84,7 +84,10 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let five_seconds = Duration::from_secs(5);
+    /// let duration = Duration::from_secs(5);
+    ///
+    /// assert_eq!(5, duration.as_secs());
+    /// assert_eq!(0, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
@@ -99,7 +102,10 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let five_seconds = Duration::from_millis(5000);
+    /// let duration = Duration::from_millis(2569);
+    ///
+    /// assert_eq!(2, duration.as_secs());
+    /// assert_eq!(569000000, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
@@ -119,9 +125,24 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let five_seconds = Duration::new(5, 0);
-    /// assert_eq!(five_seconds.as_secs(), 5);
+    /// let duration = Duration::new(5, 730023852);
+    /// assert_eq!(duration.as_secs(), 5);
+    /// ```
+    ///
+    /// To determine the total number of seconds represented by the `Duration`,
+    /// use `as_secs` in combination with [`subsec_nanos`]:
+    ///
     /// ```
+    /// use std::time::Duration;
+    ///
+    /// let duration = Duration::new(5, 730023852);
+    ///
+    /// assert_eq!(5.730023852,
+    ///            duration.as_secs() as f64
+    ///            + duration.subsec_nanos() as f64 * 1e-9);
+    /// ```
+    ///
+    /// [`subsec_nanos`]: #method.subsec_nanos
     #[stable(feature = "duration", since = "1.3.0")]
     #[inline]
     pub fn as_secs(&self) -> u64 { self.secs }