about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/Cargo.toml3
-rw-r--r--src/libcore/array.rs53
-rw-r--r--src/libcore/benches/iter.rs157
-rw-r--r--src/libcore/benches/lib.rs2
-rw-r--r--src/libcore/benches/mem.rs70
-rw-r--r--src/libcore/benches/slice.rs67
-rw-r--r--src/libcore/cell.rs54
-rw-r--r--src/libcore/char_private.rs157
-rw-r--r--src/libcore/cmp.rs8
-rw-r--r--src/libcore/convert.rs41
-rw-r--r--src/libcore/fmt/builders.rs10
-rw-r--r--src/libcore/fmt/mod.rs84
-rw-r--r--src/libcore/fmt/num.rs3
-rw-r--r--src/libcore/hash/mod.rs30
-rw-r--r--src/libcore/hash/sip.rs7
-rw-r--r--src/libcore/internal_macros.rs19
-rw-r--r--src/libcore/intrinsics.rs25
-rw-r--r--src/libcore/iter/iterator.rs351
-rw-r--r--src/libcore/iter/mod.rs624
-rw-r--r--src/libcore/iter/range.rs2
-rw-r--r--src/libcore/iter/traits.rs65
-rw-r--r--src/libcore/lib.rs20
-rw-r--r--src/libcore/macros.rs32
-rw-r--r--src/libcore/marker.rs11
-rw-r--r--src/libcore/mem.rs92
-rw-r--r--src/libcore/nonzero.rs4
-rw-r--r--src/libcore/num/mod.rs858
-rw-r--r--src/libcore/num/wrapping.rs12
-rw-r--r--src/libcore/ops/arith.rs10
-rw-r--r--src/libcore/ops/bit.rs10
-rw-r--r--src/libcore/ops/deref.rs8
-rw-r--r--src/libcore/ops/generator.rs4
-rw-r--r--src/libcore/ops/mod.rs2
-rw-r--r--src/libcore/ops/try.rs31
-rw-r--r--src/libcore/ops/unsize.rs2
-rw-r--r--src/libcore/option.rs63
-rw-r--r--src/libcore/ptr.rs66
-rw-r--r--src/libcore/result.rs2
-rw-r--r--src/libcore/slice/mod.rs224
-rw-r--r--src/libcore/str/mod.rs27
-rw-r--r--src/libcore/sync/atomic.rs85
-rw-r--r--src/libcore/tests/array.rs23
-rw-r--r--src/libcore/tests/char.rs1
-rw-r--r--src/libcore/tests/hash/mod.rs15
-rw-r--r--src/libcore/tests/hash/sip.rs14
-rw-r--r--src/libcore/tests/iter.rs403
-rw-r--r--src/libcore/tests/lib.rs9
-rw-r--r--src/libcore/tests/mem.rs16
-rw-r--r--src/libcore/tests/num/flt2dec/estimator.rs5
-rw-r--r--src/libcore/tests/num/flt2dec/mod.rs86
-rw-r--r--src/libcore/tests/num/flt2dec/strategy/grisu.rs48
-rw-r--r--src/libcore/tests/num/mod.rs10
-rw-r--r--src/libcore/tests/option.rs27
-rw-r--r--src/libcore/tests/ptr.rs84
-rw-r--r--src/libcore/tests/result.rs29
-rw-r--r--src/libcore/tests/slice.rs148
-rw-r--r--src/libcore/unit.rs31
57 files changed, 3333 insertions, 1011 deletions
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index 178df02ccdd..5af63aa970f 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -9,9 +9,6 @@ path = "lib.rs"
 test = false
 bench = false
 
-[dev-dependencies]
-rand = { path = "../librand" }
-
 [[test]]
 name = "coretests"
 path = "../libcore/tests/lib.rs"
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 6a7926fecde..3d24f8902bd 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -21,6 +21,7 @@
 
 use borrow::{Borrow, BorrowMut};
 use cmp::Ordering;
+use convert::TryFrom;
 use fmt;
 use hash::{Hash, self};
 use marker::Unsize;
@@ -57,6 +58,30 @@ unsafe impl<T, A: Unsize<[T]>> FixedSizeArray<T> for A {
     }
 }
 
+/// The error type returned when a conversion from a slice to an array fails.
+#[unstable(feature = "try_from", issue = "33417")]
+#[derive(Debug, Copy, Clone)]
+pub struct TryFromSliceError(());
+
+impl fmt::Display for TryFromSliceError {
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Display::fmt(self.__description(), f)
+    }
+}
+
+impl TryFromSliceError {
+    #[unstable(feature = "array_error_internals",
+           reason = "available through Error trait and this method should not \
+                     be exposed publicly",
+           issue = "0")]
+    #[inline]
+    #[doc(hidden)]
+    pub fn __description(&self) -> &str {
+        "could not convert slice to array"
+    }
+}
+
 macro_rules! __impl_slice_eq1 {
     ($Lhs: ty, $Rhs: ty) => {
         __impl_slice_eq1! { $Lhs, $Rhs, Sized }
@@ -123,6 +148,34 @@ macro_rules! array_impls {
                 }
             }
 
+            #[unstable(feature = "try_from", issue = "33417")]
+            impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
+                type Error = TryFromSliceError;
+
+                fn try_from(slice: &[T]) -> Result<&[T; $N], TryFromSliceError> {
+                    if slice.len() == $N {
+                        let ptr = slice.as_ptr() as *const [T; $N];
+                        unsafe { Ok(&*ptr) }
+                    } else {
+                        Err(TryFromSliceError(()))
+                    }
+                }
+            }
+
+            #[unstable(feature = "try_from", issue = "33417")]
+            impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
+                type Error = TryFromSliceError;
+
+                fn try_from(slice: &mut [T]) -> Result<&mut [T; $N], TryFromSliceError> {
+                    if slice.len() == $N {
+                        let ptr = slice.as_mut_ptr() as *mut [T; $N];
+                        unsafe { Ok(&mut *ptr) }
+                    } else {
+                        Err(TryFromSliceError(()))
+                    }
+                }
+            }
+
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<T: Hash> Hash for [T; $N] {
                 fn hash<H: hash::Hasher>(&self, state: &mut H) {
diff --git a/src/libcore/benches/iter.rs b/src/libcore/benches/iter.rs
index 827c6354c60..b284d855c45 100644
--- a/src/libcore/benches/iter.rs
+++ b/src/libcore/benches/iter.rs
@@ -147,40 +147,137 @@ fn bench_for_each_chain_ref_fold(b: &mut Bencher) {
     });
 }
 
-#[bench]
-fn bench_flat_map_sum(b: &mut Bencher) {
-    b.iter(|| -> i64 {
-        (0i64..1000).flat_map(|x| x..x+1000)
-            .map(black_box)
-            .sum()
-    });
+
+/// Helper to benchmark `sum` for iterators taken by value which
+/// can optimize `fold`, and by reference which cannot.
+macro_rules! bench_sums {
+    ($bench_sum:ident, $bench_ref_sum:ident, $iter:expr) => {
+        #[bench]
+        fn $bench_sum(b: &mut Bencher) {
+            b.iter(|| -> i64 {
+                $iter.map(black_box).sum()
+            });
+        }
+
+        #[bench]
+        fn $bench_ref_sum(b: &mut Bencher) {
+            b.iter(|| -> i64 {
+                $iter.map(black_box).by_ref().sum()
+            });
+        }
+    }
 }
 
-#[bench]
-fn bench_flat_map_ref_sum(b: &mut Bencher) {
-    b.iter(|| -> i64 {
-        (0i64..1000).flat_map(|x| x..x+1000)
-            .map(black_box)
-            .by_ref()
-            .sum()
-    });
+bench_sums! {
+    bench_flat_map_sum,
+    bench_flat_map_ref_sum,
+    (0i64..1000).flat_map(|x| x..x+1000)
 }
 
-#[bench]
-fn bench_flat_map_chain_sum(b: &mut Bencher) {
-    b.iter(|| -> i64 {
-        (0i64..1000000).flat_map(|x| once(x).chain(once(x)))
-            .map(black_box)
-            .sum()
-    });
+bench_sums! {
+    bench_flat_map_chain_sum,
+    bench_flat_map_chain_ref_sum,
+    (0i64..1000000).flat_map(|x| once(x).chain(once(x)))
 }
 
-#[bench]
-fn bench_flat_map_chain_ref_sum(b: &mut Bencher) {
-    b.iter(|| -> i64 {
-        (0i64..1000000).flat_map(|x| once(x).chain(once(x)))
-            .map(black_box)
-            .by_ref()
-            .sum()
-    });
+bench_sums! {
+    bench_enumerate_sum,
+    bench_enumerate_ref_sum,
+    (0i64..1000000).enumerate().map(|(i, x)| x * i as i64)
+}
+
+bench_sums! {
+    bench_enumerate_chain_sum,
+    bench_enumerate_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).enumerate().map(|(i, x)| x * i as i64)
+}
+
+bench_sums! {
+    bench_filter_sum,
+    bench_filter_ref_sum,
+    (0i64..1000000).filter(|x| x % 2 == 0)
+}
+
+bench_sums! {
+    bench_filter_chain_sum,
+    bench_filter_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).filter(|x| x % 2 == 0)
+}
+
+bench_sums! {
+    bench_filter_map_sum,
+    bench_filter_map_ref_sum,
+    (0i64..1000000).filter_map(|x| x.checked_mul(x))
+}
+
+bench_sums! {
+    bench_filter_map_chain_sum,
+    bench_filter_map_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).filter_map(|x| x.checked_mul(x))
+}
+
+bench_sums! {
+    bench_fuse_sum,
+    bench_fuse_ref_sum,
+    (0i64..1000000).fuse()
+}
+
+bench_sums! {
+    bench_fuse_chain_sum,
+    bench_fuse_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).fuse()
+}
+
+bench_sums! {
+    bench_inspect_sum,
+    bench_inspect_ref_sum,
+    (0i64..1000000).inspect(|_| {})
+}
+
+bench_sums! {
+    bench_inspect_chain_sum,
+    bench_inspect_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).inspect(|_| {})
+}
+
+bench_sums! {
+    bench_peekable_sum,
+    bench_peekable_ref_sum,
+    (0i64..1000000).peekable()
+}
+
+bench_sums! {
+    bench_peekable_chain_sum,
+    bench_peekable_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).peekable()
+}
+
+bench_sums! {
+    bench_skip_sum,
+    bench_skip_ref_sum,
+    (0i64..1000000).skip(1000)
+}
+
+bench_sums! {
+    bench_skip_chain_sum,
+    bench_skip_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).skip(1000)
+}
+
+bench_sums! {
+    bench_skip_while_sum,
+    bench_skip_while_ref_sum,
+    (0i64..1000000).skip_while(|&x| x < 1000)
+}
+
+bench_sums! {
+    bench_skip_while_chain_sum,
+    bench_skip_while_chain_ref_sum,
+    (0i64..1000000).chain(0..1000000).skip_while(|&x| x < 1000)
+}
+
+bench_sums! {
+    bench_take_while_chain_sum,
+    bench_take_while_chain_ref_sum,
+    (0i64..1000000).chain(1000000..).take_while(|&x| x < 1111111)
 }
diff --git a/src/libcore/benches/lib.rs b/src/libcore/benches/lib.rs
index d2db329da79..201064e823b 100644
--- a/src/libcore/benches/lib.rs
+++ b/src/libcore/benches/lib.rs
@@ -20,6 +20,6 @@ extern crate test;
 mod any;
 mod hash;
 mod iter;
-mod mem;
 mod num;
 mod ops;
+mod slice;
diff --git a/src/libcore/benches/mem.rs b/src/libcore/benches/mem.rs
deleted file mode 100644
index 8e541d92a7f..00000000000
--- a/src/libcore/benches/mem.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// 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.
-
-use test::Bencher;
-
-// FIXME #13642 (these benchmarks should be in another place)
-// Completely miscellaneous language-construct benchmarks.
-// Static/dynamic method dispatch
-
-struct Struct {
-    field: isize
-}
-
-trait Trait {
-    fn method(&self) -> isize;
-}
-
-impl Trait for Struct {
-    fn method(&self) -> isize {
-        self.field
-    }
-}
-
-#[bench]
-fn trait_vtable_method_call(b: &mut Bencher) {
-    let s = Struct { field: 10 };
-    let t = &s as &Trait;
-    b.iter(|| {
-        t.method()
-    });
-}
-
-#[bench]
-fn trait_static_method_call(b: &mut Bencher) {
-    let s = Struct { field: 10 };
-    b.iter(|| {
-        s.method()
-    });
-}
-
-// Overhead of various match forms
-
-#[bench]
-fn match_option_some(b: &mut Bencher) {
-    let x = Some(10);
-    b.iter(|| {
-        match x {
-            Some(y) => y,
-            None => 11
-        }
-    });
-}
-
-#[bench]
-fn match_vec_pattern(b: &mut Bencher) {
-    let x = [1,2,3,4,5,6];
-    b.iter(|| {
-        match x {
-            [1,2,3,..] => 10,
-            _ => 11,
-        }
-    });
-}
diff --git a/src/libcore/benches/slice.rs b/src/libcore/benches/slice.rs
new file mode 100644
index 00000000000..b2fc74544f1
--- /dev/null
+++ b/src/libcore/benches/slice.rs
@@ -0,0 +1,67 @@
+// 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.
+
+use test::black_box;
+use test::Bencher;
+
+enum Cache {
+    L1,
+    L2,
+    L3,
+}
+
+fn binary_search<F>(b: &mut Bencher, cache: Cache, mapper: F)
+    where F: Fn(usize) -> usize
+{
+    let size = match cache {
+        Cache::L1 => 1000, // 8kb
+        Cache::L2 => 10_000, // 80kb
+        Cache::L3 => 1_000_000, // 8Mb
+    };
+    let v = (0..size).map(&mapper).collect::<Vec<_>>();
+    let mut r = 0usize;
+    b.iter(move || {
+        // LCG constants from https://en.wikipedia.org/wiki/Numerical_Recipes.
+        r = r.wrapping_mul(1664525).wrapping_add(1013904223);
+        // Lookup the whole range to get 50% hits and 50% misses.
+        let i = mapper(r % size);
+        black_box(v.binary_search(&i).is_ok());
+    })
+}
+
+#[bench]
+fn binary_search_l1(b: &mut Bencher) {
+    binary_search(b, Cache::L1, |i| i * 2);
+}
+
+#[bench]
+fn binary_search_l2(b: &mut Bencher) {
+    binary_search(b, Cache::L2, |i| i * 2);
+}
+
+#[bench]
+fn binary_search_l3(b: &mut Bencher) {
+    binary_search(b, Cache::L3, |i| i * 2);
+}
+
+#[bench]
+fn binary_search_l1_with_dups(b: &mut Bencher) {
+    binary_search(b, Cache::L1, |i| i / 16 * 16);
+}
+
+#[bench]
+fn binary_search_l2_with_dups(b: &mut Bencher) {
+    binary_search(b, Cache::L2, |i| i / 16 * 16);
+}
+
+#[bench]
+fn binary_search_l3_with_dups(b: &mut Bencher) {
+    binary_search(b, Cache::L3, |i| i / 16 * 16);
+}
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index b9c5ff10f87..d4cd3f6264e 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -329,7 +329,6 @@ impl<T> Cell<T> {
     /// let c = Cell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_cell_new"))]
     #[inline]
     pub const fn new(value: T) -> Cell<T> {
         Cell {
@@ -544,7 +543,6 @@ impl<T> RefCell<T> {
     /// let c = RefCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_refcell_new"))]
     #[inline]
     pub const fn new(value: T) -> RefCell<T> {
         RefCell {
@@ -579,25 +577,51 @@ impl<T> RefCell<T> {
     ///
     /// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
     ///
+    /// # Panics
+    ///
+    /// Panics if the value is currently borrowed.
+    ///
     /// # Examples
     ///
     /// ```
     /// #![feature(refcell_replace_swap)]
     /// use std::cell::RefCell;
-    /// let c = RefCell::new(5);
-    /// let u = c.replace(6);
-    /// assert_eq!(u, 5);
-    /// assert_eq!(c, RefCell::new(6));
+    /// let cell = RefCell::new(5);
+    /// let old_value = cell.replace(6);
+    /// assert_eq!(old_value, 5);
+    /// assert_eq!(cell, RefCell::new(6));
     /// ```
+    #[inline]
+    #[unstable(feature = "refcell_replace_swap", issue="43570")]
+    pub fn replace(&self, t: T) -> T {
+        mem::replace(&mut *self.borrow_mut(), t)
+    }
+
+    /// Replaces the wrapped value with a new one computed from `f`, returning
+    /// the old value, without deinitializing either one.
+    ///
+    /// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
     ///
     /// # Panics
     ///
-    /// This function will panic if the `RefCell` has any outstanding borrows,
-    /// whether or not they are full mutable borrows.
+    /// Panics if the value is currently borrowed.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(refcell_replace_swap)]
+    /// use std::cell::RefCell;
+    /// let cell = RefCell::new(5);
+    /// let old_value = cell.replace_with(|&mut old| old + 1);
+    /// assert_eq!(old_value, 5);
+    /// assert_eq!(cell, RefCell::new(6));
+    /// ```
     #[inline]
     #[unstable(feature = "refcell_replace_swap", issue="43570")]
-    pub fn replace(&self, t: T) -> T {
-        mem::replace(&mut *self.borrow_mut(), t)
+    pub fn replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> T {
+        let mut_borrow = &mut *self.borrow_mut();
+        let replacement = f(mut_borrow);
+        mem::replace(mut_borrow, replacement)
     }
 
     /// Swaps the wrapped value of `self` with the wrapped value of `other`,
@@ -605,6 +629,10 @@ impl<T> RefCell<T> {
     ///
     /// This function corresponds to [`std::mem::swap`](../mem/fn.swap.html).
     ///
+    /// # Panics
+    ///
+    /// Panics if the value in either `RefCell` is currently borrowed.
+    ///
     /// # Examples
     ///
     /// ```
@@ -616,11 +644,6 @@ impl<T> RefCell<T> {
     /// assert_eq!(c, RefCell::new(6));
     /// assert_eq!(d, RefCell::new(5));
     /// ```
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if either `RefCell` has any outstanding borrows,
-    /// whether or not they are full mutable borrows.
     #[inline]
     #[unstable(feature = "refcell_replace_swap", issue="43570")]
     pub fn swap(&self, other: &Self) {
@@ -1190,7 +1213,6 @@ impl<T> UnsafeCell<T> {
     /// let uc = UnsafeCell::new(5);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_unsafe_cell_new"))]
     #[inline]
     pub const fn new(value: T) -> UnsafeCell<T> {
         UnsafeCell { value: value }
diff --git a/src/libcore/char_private.rs b/src/libcore/char_private.rs
index 2c0f449b276..e6803745ab5 100644
--- a/src/libcore/char_private.rs
+++ b/src/libcore/char_private.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -47,7 +47,7 @@ fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8],
     current
 }
 
-pub fn is_printable(x: char) -> bool {
+pub(crate) fn is_printable(x: char) -> bool {
     let x = x as u32;
     let lower = x as u16;
     if x < 0x10000 {
@@ -64,7 +64,10 @@ pub fn is_printable(x: char) -> bool {
         if 0x2b81e <= x && x < 0x2b820 {
             return false;
         }
-        if 0x2cea2 <= x && x < 0x2f800 {
+        if 0x2cea2 <= x && x < 0x2ceb0 {
+            return false;
+        }
+        if 0x2ebe1 <= x && x < 0x2f800 {
             return false;
         }
         if 0x2fa1e <= x && x < 0xe0100 {
@@ -83,12 +86,12 @@ const SINGLETONS0U: &'static [(u8, u8)] = &[
     (0x05, 8),
     (0x06, 3),
     (0x07, 4),
-    (0x08, 7),
+    (0x08, 8),
     (0x09, 16),
     (0x0a, 27),
-    (0x0b, 24),
+    (0x0b, 25),
     (0x0c, 22),
-    (0x0d, 20),
+    (0x0d, 18),
     (0x0e, 22),
     (0x0f, 4),
     (0x10, 3),
@@ -99,16 +102,15 @@ const SINGLETONS0U: &'static [(u8, u8)] = &[
     (0x18, 2),
     (0x19, 3),
     (0x1a, 7),
-    (0x1c, 1),
+    (0x1d, 1),
     (0x1f, 22),
     (0x20, 3),
-    (0x23, 1),
     (0x2b, 5),
     (0x2c, 2),
     (0x2d, 11),
     (0x2e, 1),
     (0x30, 3),
-    (0x31, 1),
+    (0x31, 3),
     (0x32, 2),
     (0xa7, 1),
     (0xa8, 2),
@@ -125,19 +127,19 @@ const SINGLETONS0L: &'static [u8] = &[
     0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57,
     0x58, 0x60, 0x88, 0x8b, 0x8c, 0x90, 0x1c, 0x1d,
     0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0x2e, 0x2f, 0x3f,
-    0x5c, 0x5d, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91,
-    0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6, 0xc9,
-    0xca, 0xde, 0xe4, 0xe5, 0x04, 0x11, 0x12, 0x29,
-    0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a,
-    0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba,
-    0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5, 0x04,
-    0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a,
-    0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65,
-    0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce, 0xcf, 0x04,
-    0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65,
-    0x84, 0x8d, 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5,
-    0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04, 0x0d, 0x11,
-    0x3b, 0x3c, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
+    0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e,
+    0x91, 0x92, 0xa9, 0xb1, 0xba, 0xbb, 0xc5, 0xc6,
+    0xc9, 0xca, 0xde, 0xe4, 0xe5, 0x04, 0x11, 0x12,
+    0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49,
+    0x4a, 0x5d, 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4,
+    0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, 0xe4, 0xe5,
+    0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31,
+    0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e,
+    0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, 0xc9, 0xce,
+    0xcf, 0x04, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57,
+    0x64, 0x65, 0x84, 0x8d, 0x91, 0xa9, 0xb4, 0xba,
+    0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x04,
+    0x0d, 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x81,
     0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, 0xd7, 0xf0,
     0xf1, 0x83, 0x85, 0x86, 0x89, 0x8b, 0x8c, 0x98,
     0xa0, 0xa4, 0xa6, 0xa8, 0xa9, 0xac, 0xba, 0xbe,
@@ -148,18 +150,18 @@ const SINGLETONS0L: &'static [u8] = &[
     0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, 0xfe,
     0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e,
     0x0f, 0x1f, 0x6e, 0x6f, 0x1c, 0x1d, 0x5f, 0x7d,
-    0x7e, 0xae, 0xaf, 0xf7, 0x16, 0x17, 0x1e, 0x1f,
+    0x7e, 0xae, 0xaf, 0xfa, 0x16, 0x17, 0x1e, 0x1f,
     0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e,
     0x7e, 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0,
-    0xf1, 0xf5, 0x72, 0x73, 0x8f, 0xff, 0x74, 0x75,
-    0x96, 0x97, 0xc9, 0x2f, 0x5f, 0x26, 0x2e, 0x2f,
-    0xa7, 0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf,
-    0x9a, 0x40, 0x97, 0x98, 0x8f, 0x1f, 0xff, 0xaf,
-    0xfe, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b,
-    0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee, 0xef,
-    0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90,
-    0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9,
-    0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
+    0xf1, 0xf5, 0x72, 0x73, 0x8f, 0x74, 0x75, 0x96,
+    0x97, 0xc9, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7,
+    0xaf, 0xb7, 0xbf, 0xc7, 0xcf, 0xd7, 0xdf, 0x9a,
+    0x40, 0x97, 0x98, 0x2f, 0x30, 0x8f, 0x1f, 0xff,
+    0xaf, 0xfe, 0xff, 0xce, 0xff, 0x4e, 0x4f, 0x5a,
+    0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, 0x2f, 0xee,
+    0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45,
+    0x90, 0x91, 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8,
+    0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, 0xfe, 0xff,
 ];
 const SINGLETONS1U: &'static [(u8, u8)] = &[
     (0x00, 6),
@@ -176,7 +178,9 @@ const SINGLETONS1U: &'static [(u8, u8)] = &[
     (0x13, 18),
     (0x14, 2),
     (0x15, 2),
+    (0x1a, 3),
     (0x1c, 5),
+    (0x1d, 4),
     (0x24, 1),
     (0x6a, 3),
     (0x6b, 2),
@@ -192,7 +196,7 @@ const SINGLETONS1U: &'static [(u8, u8)] = &[
     (0xee, 32),
     (0xf0, 4),
     (0xf1, 1),
-    (0xf9, 4),
+    (0xf9, 1),
 ];
 const SINGLETONS1L: &'static [u8] = &[
     0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e,
@@ -202,18 +206,18 @@ const SINGLETONS1L: &'static [u8] = &[
     0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12,
     0x29, 0x31, 0x34, 0x3a, 0x3b, 0x45, 0x46, 0x49,
     0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5a, 0x5c, 0xb6,
-    0xb7, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x6f, 0x5f,
-    0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28,
-    0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8,
-    0xad, 0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15,
-    0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc,
-    0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0xc5,
-    0xc6, 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33,
-    0x38, 0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55,
-    0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65,
-    0x66, 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4,
-    0xaa, 0xaf, 0xb0, 0xc0, 0xd0, 0x2f, 0x1f, 0x31,
-    0x32, 0x3f,
+    0xb7, 0x84, 0x85, 0x9d, 0x09, 0x37, 0x90, 0x91,
+    0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x6f, 0x5f, 0xee,
+    0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, 0x28, 0x55,
+    0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad,
+    0xba, 0xbc, 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d,
+    0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, 0xcc, 0xcd,
+    0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0xc5, 0xc6,
+    0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38,
+    0x3a, 0x48, 0x4a, 0x4c, 0x50, 0x53, 0x55, 0x56,
+    0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66,
+    0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa,
+    0xaf, 0xb0, 0xc0, 0xd0, 0x2f, 0x3f,
 ];
 const NORMAL0: &'static [u8] = &[
     0x00, 0x20,
@@ -224,12 +228,12 @@ const NORMAL0: &'static [u8] = &[
     0x05, 0x11,
     0x81, 0xac, 0x0e,
     0x3b, 0x05,
-    0x5f, 0x41,
+    0x6b, 0x35,
     0x1e, 0x16,
     0x80, 0xdf, 0x03,
     0x19, 0x08,
     0x01, 0x04,
-    0x20, 0x05,
+    0x22, 0x03,
     0x0a, 0x04,
     0x34, 0x04,
     0x07, 0x03,
@@ -238,8 +242,7 @@ const NORMAL0: &'static [u8] = &[
     0x10, 0x0b,
     0x50, 0x0f,
     0x12, 0x07,
-    0x01, 0x07,
-    0x4d, 0x08,
+    0x55, 0x08,
     0x02, 0x04,
     0x1c, 0x0a,
     0x09, 0x03,
@@ -258,8 +261,8 @@ const NORMAL0: &'static [u8] = &[
     0x10, 0x08,
     0x56, 0x07,
     0x02, 0x07,
-    0x15, 0x0e,
-    0x4f, 0x04,
+    0x15, 0x0d,
+    0x50, 0x04,
     0x43, 0x03,
     0x2d, 0x03,
     0x01, 0x04,
@@ -304,34 +307,32 @@ const NORMAL0: &'static [u8] = &[
     0x3c, 0x37,
     0x08, 0x08,
     0x2a, 0x06,
-    0x80, 0xf6, 0x05,
-    0x82, 0x04, 0x11,
+    0x82, 0xff, 0x11,
     0x18, 0x08,
     0x2f, 0x11,
     0x2d, 0x03,
-    0x1f, 0x11,
+    0x20, 0x10,
     0x21, 0x0f,
     0x80, 0x8c, 0x04,
     0x82, 0x97, 0x19,
     0x0b, 0x15,
     0x87, 0x5a, 0x03,
-    0x15, 0x1a,
+    0x16, 0x19,
     0x04, 0x10,
     0x80, 0xf4, 0x05,
     0x2f, 0x05,
     0x3b, 0x07,
     0x02, 0x0e,
     0x18, 0x09,
-    0x80, 0xa5, 0x3b,
+    0x80, 0xaa, 0x36,
     0x74, 0x0c,
     0x80, 0xd6, 0x1a,
     0x0c, 0x05,
     0x80, 0xff, 0x05,
-    0x29, 0x03,
-    0x80, 0x8a, 0x05,
+    0x80, 0xb6, 0x05,
     0x24, 0x0c,
     0x9b, 0xc6, 0x0a,
-    0xd2, 0x16, 0x2a,
+    0xd2, 0x2b, 0x15,
     0x84, 0x8d, 0x03,
     0x37, 0x09,
     0x81, 0x5c, 0x14,
@@ -378,8 +379,8 @@ const NORMAL1: &'static [u8] = &[
     0x1d, 0x03,
     0x31, 0x0f,
     0x1c, 0x04,
-    0x24, 0x0c,
-    0x1b, 0x05,
+    0x24, 0x09,
+    0x1e, 0x05,
     0x2b, 0x05,
     0x44, 0x04,
     0x0e, 0x2a,
@@ -447,11 +448,16 @@ const NORMAL1: &'static [u8] = &[
     0x0f, 0x04,
     0x10, 0x81, 0x60,
     0x53, 0x0c,
-    0x01, 0x81, 0xc0,
+    0x01, 0x81, 0x00,
+    0x48, 0x08,
+    0x53, 0x1d,
     0x39, 0x81, 0x07,
     0x46, 0x0a,
     0x1d, 0x03,
-    0x47, 0x83, 0x49,
+    0x47, 0x49,
+    0x37, 0x03,
+    0x0e, 0x08,
+    0x0a, 0x82, 0xa6,
     0x83, 0x9a, 0x66,
     0x75, 0x0b,
     0x80, 0xc4, 0x8a, 0xbc,
@@ -467,10 +473,11 @@ const NORMAL1: &'static [u8] = &[
     0x45, 0x0b,
     0x2f, 0x10,
     0x11, 0x40,
-    0x01, 0x1f,
+    0x02, 0x1e,
     0x97, 0xed, 0x13,
     0x82, 0xf3, 0xa5, 0x0d,
-    0x02, 0x8b, 0xfe,
+    0x81, 0x1f, 0x51,
+    0x81, 0x8c, 0x89, 0x04,
     0x6b, 0x05,
     0x0d, 0x03,
     0x09, 0x07,
@@ -503,20 +510,22 @@ const NORMAL1: &'static [u8] = &[
     0x1d, 0x0d,
     0x2c, 0x04,
     0x09, 0x07,
-    0x02, 0x80, 0xae,
-    0x83, 0xd3, 0x0d,
+    0x02, 0x0e,
+    0x06, 0x80, 0x9a,
+    0x83, 0xd5, 0x0b,
     0x0d, 0x03,
-    0x07, 0x09,
+    0x09, 0x07,
     0x74, 0x0c,
     0x55, 0x2b,
     0x0c, 0x04,
     0x38, 0x08,
     0x0a, 0x06,
     0x28, 0x08,
-    0x1e, 0x62,
-    0x18, 0x08,
-    0x1c, 0x04,
-    0x0f, 0x21,
-    0x12, 0x2e,
-    0x01, 0x86, 0x3f,
+    0x1e, 0x52,
+    0x0c, 0x04,
+    0x3d, 0x03,
+    0x1c, 0x14,
+    0x18, 0x28,
+    0x01, 0x0f,
+    0x17, 0x86, 0x19,
 ];
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 6f86f8caad0..cc71e09caea 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -162,8 +162,8 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait Eq: PartialEq<Self> {
-    // FIXME #13101: this method is used solely by #[deriving] to
-    // assert that every component of a type implements #[deriving]
+    // this method is used solely by #[deriving] to assert
+    // that every component of a type implements #[deriving]
     // itself, the current deriving infrastructure means doing this
     // assertion without using a method on this trait is nearly
     // impossible.
@@ -456,7 +456,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(2, 1.max(2));
     /// assert_eq!(2, 2.max(2));
     /// ```
-    #[stable(feature = "ord_max_min", since = "1.22.0")]
+    #[stable(feature = "ord_max_min", since = "1.21.0")]
     fn max(self, other: Self) -> Self
     where Self: Sized {
         if other >= self { other } else { self }
@@ -472,7 +472,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     /// assert_eq!(1, 1.min(2));
     /// assert_eq!(2, 2.min(2));
     /// ```
-    #[stable(feature = "ord_max_min", since = "1.22.0")]
+    #[stable(feature = "ord_max_min", since = "1.21.0")]
     fn min(self, other: Self) -> Self
     where Self: Sized {
         if self <= other { self } else { other }
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 6f3c3863fae..e815d72d366 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -48,8 +48,25 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use str::FromStr;
+use fmt;
 
+/// A type used as the error type for implementations of fallible conversion
+/// traits in cases where conversions cannot actually fail.
+///
+/// Because `Infallible` has no variants, a value of this type can never exist.
+/// It is used only to satisfy trait signatures that expect an error type, and
+/// signals to both the compiler and the user that the error case is impossible.
+#[unstable(feature = "try_from", issue = "33417")]
+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+pub enum Infallible {}
+
+#[unstable(feature = "try_from", issue = "33417")]
+impl fmt::Display for Infallible {
+    fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+        }
+    }
+}
 /// A cheap reference-to-reference conversion. Used to convert a value to a
 /// reference value within generic code.
 ///
@@ -417,6 +434,17 @@ impl<T, U> TryInto<U> for T where U: TryFrom<T>
     }
 }
 
+// Infallible conversions are semantically equivalent to fallible conversions
+// with an uninhabited error type.
+#[unstable(feature = "try_from", issue = "33417")]
+impl<T, U> TryFrom<U> for T where T: From<U> {
+    type Error = Infallible;
+
+    fn try_from(value: U) -> Result<Self, Self::Error> {
+        Ok(T::from(value))
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // CONCRETE IMPLS
 ////////////////////////////////////////////////////////////////////////////////
@@ -442,14 +470,3 @@ impl AsRef<str> for str {
         self
     }
 }
-
-// FromStr implies TryFrom<&str>
-#[unstable(feature = "try_from", issue = "33417")]
-impl<'a, T> TryFrom<&'a str> for T where T: FromStr
-{
-    type Error = <T as FromStr>::Err;
-
-    fn try_from(s: &'a str) -> Result<T, Self::Error> {
-        FromStr::from_str(s)
-    }
-}
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index b594c886b64..60b9eeb1283 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use fmt::{self, FlagV1};
+use fmt;
 
 struct PadAdapter<'a, 'b: 'a> {
     fmt: &'a mut fmt::Formatter<'b>,
@@ -140,7 +140,7 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
     }
 
     fn is_pretty(&self) -> bool {
-        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+        self.fmt.alternate()
     }
 }
 
@@ -233,7 +233,7 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
     }
 
     fn is_pretty(&self) -> bool {
-        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+        self.fmt.alternate()
     }
 }
 
@@ -277,7 +277,7 @@ impl<'a, 'b: 'a> DebugInner<'a, 'b> {
     }
 
     fn is_pretty(&self) -> bool {
-        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+        self.fmt.alternate()
     }
 }
 
@@ -519,6 +519,6 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     }
 
     fn is_pretty(&self) -> bool {
-        self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
+        self.fmt.alternate()
     }
 }
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index b84a1deb611..551aa929ce4 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -261,6 +261,14 @@ pub struct Formatter<'a> {
 
 struct Void {
     _priv: (),
+    /// Erases all oibits, because `Void` erases the type of the object that
+    /// will be used to produce formatted output. Since we do not know what
+    /// oibits the real types have (and they can have any or none), we need to
+    /// take the most conservative approach and forbid all oibits.
+    ///
+    /// It was added after #45197 showed that one could share a `!Sync`
+    /// object across threads by passing it into `format_args!`.
+    _oibit_remover: PhantomData<*mut Fn()>,
 }
 
 /// This struct represents the generic "argument" which is taken by the Xprintf
@@ -322,7 +330,6 @@ impl<'a> ArgumentV1<'a> {
 
 // flags available in the v1 format of format_args
 #[derive(Copy, Clone)]
-#[allow(dead_code)] // SignMinus isn't currently used
 enum FlagV1 { SignPlus, SignMinus, Alternate, SignAwareZeroPad, }
 
 impl<'a> Arguments<'a> {
@@ -427,7 +434,7 @@ impl<'a> Display for Arguments<'a> {
     }
 }
 
-/// Format trait for the `?` character.
+/// `?` formatting.
 ///
 /// `Debug` should format the output in a programmer-facing, debugging context.
 ///
@@ -488,13 +495,14 @@ impl<'a> Display for Arguments<'a> {
 /// The origin is: Point { x: 0, y: 0 }
 /// ```
 ///
-/// There are a number of `debug_*` methods on `Formatter` to help you with manual
+/// There are a number of `debug_*` methods on [`Formatter`] to help you with manual
 /// implementations, such as [`debug_struct`][debug_struct].
 ///
 /// `Debug` implementations using either `derive` or the debug builder API
-/// on `Formatter` support pretty printing using the alternate flag: `{:#?}`.
+/// on [`Formatter`] support pretty printing using the alternate flag: `{:#?}`.
 ///
 /// [debug_struct]: ../../std/fmt/struct.Formatter.html#method.debug_struct
+/// [`Formatter`]: ../../std/fmt/struct.Formatter.html
 ///
 /// Pretty printing with `#?`:
 ///
@@ -525,6 +533,26 @@ impl<'a> Display for Arguments<'a> {
 #[lang = "debug_trait"]
 pub trait Debug {
     /// Formats the value using the given formatter.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fmt;
+    ///
+    /// struct Position {
+    ///     longitude: f32,
+    ///     latitude: f32,
+    /// }
+    ///
+    /// impl fmt::Debug for Position {
+    ///     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    ///         write!(f, "({:?}, {:?})", self.longitude, self.latitude)
+    ///     }
+    /// }
+    ///
+    /// assert_eq!("(1.987, 2.983)".to_owned(),
+    ///            format!("{:?}", Position { longitude: 1.987, latitude: 2.983, }));
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
@@ -592,10 +620,13 @@ pub trait Display {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `o` character.
+/// `o` formatting.
 ///
 /// The `Octal` trait should format its output as a number in base-8.
 ///
+/// For primitive signed integers (`i8` to `i128`, and `isize`),
+/// negative values are formatted as the two’s complement representation.
+///
 /// The alternate flag, `#`, adds a `0o` in front of the output.
 ///
 /// For more information on formatters, see [the module-level documentation][module].
@@ -611,6 +642,8 @@ pub trait Display {
 ///
 /// assert_eq!(format!("{:o}", x), "52");
 /// assert_eq!(format!("{:#o}", x), "0o52");
+///
+/// assert_eq!(format!("{:o}", -16), "37777777760");
 /// ```
 ///
 /// Implementing `Octal` on a type:
@@ -639,10 +672,13 @@ pub trait Octal {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `b` character.
+/// `b` formatting.
 ///
 /// The `Binary` trait should format its output as a number in binary.
 ///
+/// For primitive signed integers (`i8` to `i128`, and `isize`),
+/// negative values are formatted as the two’s complement representation.
+///
 /// The alternate flag, `#`, adds a `0b` in front of the output.
 ///
 /// For more information on formatters, see [the module-level documentation][module].
@@ -658,6 +694,8 @@ pub trait Octal {
 ///
 /// assert_eq!(format!("{:b}", x), "101010");
 /// assert_eq!(format!("{:#b}", x), "0b101010");
+///
+/// assert_eq!(format!("{:b}", -16), "11111111111111111111111111110000");
 /// ```
 ///
 /// Implementing `Binary` on a type:
@@ -686,11 +724,14 @@ pub trait Binary {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `x` character.
+/// `x` formatting.
 ///
 /// The `LowerHex` trait should format its output as a number in hexadecimal, with `a` through `f`
 /// in lower case.
 ///
+/// For primitive signed integers (`i8` to `i128`, and `isize`),
+/// negative values are formatted as the two’s complement representation.
+///
 /// The alternate flag, `#`, adds a `0x` in front of the output.
 ///
 /// For more information on formatters, see [the module-level documentation][module].
@@ -706,6 +747,8 @@ pub trait Binary {
 ///
 /// assert_eq!(format!("{:x}", x), "2a");
 /// assert_eq!(format!("{:#x}", x), "0x2a");
+///
+/// assert_eq!(format!("{:x}", -16), "fffffff0");
 /// ```
 ///
 /// Implementing `LowerHex` on a type:
@@ -734,11 +777,14 @@ pub trait LowerHex {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `X` character.
+/// `X` formatting.
 ///
 /// The `UpperHex` trait should format its output as a number in hexadecimal, with `A` through `F`
 /// in upper case.
 ///
+/// For primitive signed integers (`i8` to `i128`, and `isize`),
+/// negative values are formatted as the two’s complement representation.
+///
 /// The alternate flag, `#`, adds a `0x` in front of the output.
 ///
 /// For more information on formatters, see [the module-level documentation][module].
@@ -754,6 +800,8 @@ pub trait LowerHex {
 ///
 /// assert_eq!(format!("{:X}", x), "2A");
 /// assert_eq!(format!("{:#X}", x), "0x2A");
+///
+/// assert_eq!(format!("{:X}", -16), "FFFFFFF0");
 /// ```
 ///
 /// Implementing `UpperHex` on a type:
@@ -782,7 +830,7 @@ pub trait UpperHex {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `p` character.
+/// `p` formatting.
 ///
 /// The `Pointer` trait should format its output as a memory location. This is commonly presented
 /// as hexadecimal.
@@ -827,7 +875,7 @@ pub trait Pointer {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `e` character.
+/// `e` formatting.
 ///
 /// The `LowerExp` trait should format its output in scientific notation with a lower-case `e`.
 ///
@@ -870,7 +918,7 @@ pub trait LowerExp {
     fn fmt(&self, f: &mut Formatter) -> Result;
 }
 
-/// Format trait for the `E` character.
+/// `E` formatting.
 ///
 /// The `UpperExp` trait should format its output in scientific notation with an upper-case `E`.
 ///
@@ -932,7 +980,7 @@ pub trait UpperExp {
 /// assert_eq!(output, "Hello world!");
 /// ```
 ///
-/// Please note that using [`write!`] might be preferrable. Example:
+/// Please note that using [`write!`] might be preferable. Example:
 ///
 /// ```
 /// use std::fmt::Write;
@@ -1275,8 +1323,11 @@ impl<'a> Formatter<'a> {
         write(self.buf, fmt)
     }
 
-    /// Flags for formatting (packed version of rt::Flag)
+    /// Flags for formatting
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_deprecated(since = "1.24.0",
+                       reason = "use the `sign_plus`, `sign_minus`, `alternate`, \
+                                 or `sign_aware_zero_pad` methods instead")]
     pub fn flags(&self) -> u32 { self.flags }
 
     /// Character used as 'fill' whenever there is alignment
@@ -1321,8 +1372,11 @@ impl<'a> Formatter<'a> {
         self.flags & (1 << FlagV1::SignAwareZeroPad as u32) != 0
     }
 
-    /// Creates a `DebugStruct` builder designed to assist with creation of
-    /// `fmt::Debug` implementations for structs.
+    /// Creates a [`DebugStruct`] builder designed to assist with creation of
+    /// [`fmt::Debug`] implementations for structs.
+    ///
+    /// [`DebugStruct`]: ../../std/fmt/struct.DebugStruct.html
+    /// [`fmt::Debug`]: ../../std/fmt/trait.Debug.html
     ///
     /// # Examples
     ///
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 8ea388fddf8..ee989854a37 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -12,7 +12,6 @@
 
 #![allow(deprecated)]
 
-// FIXME: #6220 Implement floating point formatting
 
 use fmt;
 use ops::{Div, Rem, Sub};
@@ -135,7 +134,7 @@ macro_rules! radix {
     }
 }
 
-radix! { Binary,    2, "0b", x @  0 ...  2 => b'0' + x }
+radix! { Binary,    2, "0b", x @  0 ...  1 => b'0' + x }
 radix! { Octal,     8, "0o", x @  0 ...  7 => b'0' + x }
 radix! { Decimal,  10, "",   x @  0 ...  9 => b'0' + x }
 radix! { LowerHex, 16, "0x", x @  0 ...  9 => b'0' + x,
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index bc1b911cd78..15545a04b64 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -259,7 +259,7 @@ pub trait Hasher {
     /// println!("Hash is {:x}!", hasher.finish());
     /// ```
     ///
-    /// ['write']: #tymethod.write
+    /// [`write`]: #tymethod.write
     #[stable(feature = "rust1", since = "1.0.0")]
     fn finish(&self) -> u64;
 
@@ -665,16 +665,36 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<T> Hash for *const T {
+    impl<T: ?Sized> Hash for *const T {
         fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write_usize(*self as usize)
+            if mem::size_of::<Self>() == mem::size_of::<usize>() {
+                // Thin pointer
+                state.write_usize(*self as *const () as usize);
+            } else {
+                // Fat pointer
+                let (a, b) = unsafe {
+                    *(self as *const Self as *const (usize, usize))
+                };
+                state.write_usize(a);
+                state.write_usize(b);
+            }
         }
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<T> Hash for *mut T {
+    impl<T: ?Sized> Hash for *mut T {
         fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write_usize(*self as usize)
+            if mem::size_of::<Self>() == mem::size_of::<usize>() {
+                // Thin pointer
+                state.write_usize(*self as *const () as usize);
+            } else {
+                // Fat pointer
+                let (a, b) = unsafe {
+                    *(self as *const Self as *const (usize, usize))
+                };
+                state.write_usize(a);
+                state.write_usize(b);
+            }
         }
     }
 }
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 91fd01b36d4..4e4d9b3f1e2 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -22,7 +22,7 @@ use mem;
 /// This is currently the default hashing function used by standard library
 /// (eg. `collections::HashMap` uses it by default).
 ///
-/// See: https://131002.net/siphash/
+/// See: <https://131002.net/siphash>
 #[unstable(feature = "sip_hash_13", issue = "34767")]
 #[rustc_deprecated(since = "1.13.0",
                    reason = "use `std::collections::hash_map::DefaultHasher` instead")]
@@ -33,7 +33,7 @@ pub struct SipHasher13 {
 
 /// An implementation of SipHash 2-4.
 ///
-/// See: https://131002.net/siphash/
+/// See: <https://131002.net/siphash/>
 #[unstable(feature = "sip_hash_13", issue = "34767")]
 #[rustc_deprecated(since = "1.13.0",
                    reason = "use `std::collections::hash_map::DefaultHasher` instead")]
@@ -44,7 +44,7 @@ pub struct SipHasher24 {
 
 /// An implementation of SipHash 2-4.
 ///
-/// See: https://131002.net/siphash/
+/// See: <https://131002.net/siphash/>
 ///
 /// SipHash is a general-purpose hashing function: it runs at a good
 /// speed (competitive with Spooky and City) and permits strong _keyed_
@@ -72,6 +72,7 @@ struct Hasher<S: Sip> {
 }
 
 #[derive(Debug, Clone, Copy)]
+#[repr(C)]
 struct State {
     // v0, v2 and v1, v3 show up in pairs in the algorithm,
     // and simd implementations of SipHash will use vectors
diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs
index 9a7914064fd..cb215a38e53 100644
--- a/src/libcore/internal_macros.rs
+++ b/src/libcore/internal_macros.rs
@@ -68,3 +68,22 @@ macro_rules! forward_ref_binop {
         }
     }
 }
+
+// implements "T op= &U", based on "T op= U"
+// where U is expected to be `Copy`able
+macro_rules! forward_ref_op_assign {
+    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
+        forward_ref_op_assign!(impl $imp, $method for $t, $u,
+                #[stable(feature = "op_assign_builtins_by_ref", since = "1.22.0")]);
+    };
+    (impl $imp:ident, $method:ident for $t:ty, $u:ty, #[$attr:meta]) => {
+        #[$attr]
+        impl<'a> $imp<&'a $u> for $t {
+            #[inline]
+            fn $method(&mut self, other: &'a $u) {
+                $imp::$method(self, *other);
+            }
+        }
+    }
+}
+
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index bc82f0230e5..f1e51e995c2 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -627,6 +627,9 @@ extern "rust-intrinsic" {
     pub fn rustc_peek<T>(_: T) -> T;
 
     /// Aborts the execution of the process.
+    ///
+    /// The stabilized version of this intrinsic is
+    /// [`std::process::abort`](../../std/process/fn.abort.html)
     pub fn abort() -> !;
 
     /// Tells LLVM that this point in the code is not reachable, enabling
@@ -676,6 +679,10 @@ extern "rust-intrinsic" {
     pub fn min_align_of<T>() -> usize;
     pub fn pref_align_of<T>() -> usize;
 
+    /// The size of the referenced value in bytes.
+    ///
+    /// The stabilized version of this intrinsic is
+    /// [`std::mem::size_of_val`](../../std/mem/fn.size_of_val.html).
     pub fn size_of_val<T: ?Sized>(_: &T) -> usize;
     pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
 
@@ -921,6 +928,9 @@ extern "rust-intrinsic" {
     ///
     /// If the actual type neither requires drop glue nor implements
     /// `Copy`, then may return `true` or `false`.
+    ///
+    /// The stabilized version of this intrinsic is
+    /// [`std::mem::needs_drop`](../../std/mem/fn.needs_drop.html).
     pub fn needs_drop<T>() -> bool;
 
     /// Calculates the offset from a pointer.
@@ -1376,17 +1386,10 @@ extern "rust-intrinsic" {
     /// }
     /// # } }
     /// ```
-    #[cfg(not(stage0))]
     pub fn align_offset(ptr: *const (), align: usize) -> usize;
-}
 
-#[cfg(stage0)]
-/// remove me after the next release
-pub unsafe fn align_offset(ptr: *const (), align: usize) -> usize {
-    let offset = ptr as usize % align;
-    if offset == 0 {
-        0
-    } else {
-        align - offset
-    }
+    /// Emits a `!nontemporal` store according to LLVM (see their docs).
+    /// Probably will never become stable.
+    #[cfg(not(stage0))]
+    pub fn nontemporal_store<T>(ptr: *mut T, val: T);
 }
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 36bf9633b4a..7f6d627536d 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -9,7 +9,9 @@
 // except according to those terms.
 
 use cmp::Ordering;
+use ops::Try;
 
+use super::{AlwaysOk, LoopState};
 use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse};
 use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev};
 use super::{Zip, Sum, Product};
@@ -28,6 +30,7 @@ fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \
                             `.iter()` or a similar method"]
+#[doc(spotlight)]
 pub trait Iterator {
     /// The type of the elements being iterated over.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -518,7 +521,7 @@ pub trait Iterator {
     ///       .for_each(|(i, x)| println!("{}:{}", i, x));
     /// ```
     #[inline]
-    #[stable(feature = "iterator_for_each", since = "1.22.0")]
+    #[stable(feature = "iterator_for_each", since = "1.21.0")]
     fn for_each<F>(self, mut f: F) where
         Self: Sized, F: FnMut(Self::Item),
     {
@@ -1337,6 +1340,78 @@ pub trait Iterator {
         (left, right)
     }
 
+    /// An iterator method that applies a function as long as it returns
+    /// successfully, producing a single, final value.
+    ///
+    /// `try_fold()` takes two arguments: an initial value, and a closure with
+    /// two arguments: an 'accumulator', and an element. The closure either
+    /// returns successfully, with the value that the accumulator should have
+    /// for the next iteration, or it returns failure, with an error value that
+    /// is propagated back to the caller immediately (short-circuiting).
+    ///
+    /// The initial value is the value the accumulator will have on the first
+    /// call.  If applying the closure succeeded against every element of the
+    /// iterator, `try_fold()` returns the final accumulator as success.
+    ///
+    /// Folding is useful whenever you have a collection of something, and want
+    /// to produce a single value from it.
+    ///
+    /// # Note to Implementors
+    ///
+    /// Most of the other (forward) methods have default implementations in
+    /// terms of this one, so try to implement this explicitly if it can
+    /// do something better than the default `for` loop implementation.
+    ///
+    /// In particular, try to have this call `try_fold()` on the internal parts
+    /// from which this iterator is composed.  If multiple calls are needed,
+    /// the `?` operator be convenient for chaining the accumulator value along,
+    /// but beware any invariants that need to be upheld before those early
+    /// returns.  This is a `&mut self` method, so iteration needs to be
+    /// resumable after hitting an error here.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(iterator_try_fold)]
+    /// let a = [1, 2, 3];
+    ///
+    /// // the checked sum of all of the elements of the array
+    /// let sum = a.iter()
+    ///            .try_fold(0i8, |acc, &x| acc.checked_add(x));
+    ///
+    /// assert_eq!(sum, Some(6));
+    /// ```
+    ///
+    /// Short-circuiting:
+    ///
+    /// ```
+    /// #![feature(iterator_try_fold)]
+    /// let a = [10, 20, 30, 100, 40, 50];
+    /// let mut it = a.iter();
+    ///
+    /// // This sum overflows when adding the 100 element
+    /// let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x));
+    /// assert_eq!(sum, None);
+    ///
+    /// // Because it short-circuited, the remaining elements are still
+    /// // available through the iterator.
+    /// assert_eq!(it.len(), 2);
+    /// assert_eq!(it.next(), Some(&40));
+    /// ```
+    #[inline]
+    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        let mut accum = init;
+        while let Some(x) = self.next() {
+            accum = f(accum, x)?;
+        }
+        Try::from_ok(accum)
+    }
+
     /// An iterator method that applies a function, producing a single, final value.
     ///
     /// `fold()` takes two arguments: an initial value, and a closure with two
@@ -1361,7 +1436,7 @@ pub trait Iterator {
     /// ```
     /// let a = [1, 2, 3];
     ///
-    /// // the sum of all of the elements of a
+    /// // the sum of all of the elements of the array
     /// let sum = a.iter()
     ///            .fold(0, |acc, &x| acc + x);
     ///
@@ -1403,14 +1478,10 @@ pub trait Iterator {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn fold<B, F>(self, init: B, mut f: F) -> B where
+    fn fold<B, F>(mut self, init: B, mut f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
-        let mut accum = init;
-        for x in self {
-            accum = f(accum, x);
-        }
-        accum
+        self.try_fold(init, move |acc, x| AlwaysOk(f(acc, x))).0
     }
 
     /// Tests if every element of the iterator matches a predicate.
@@ -1455,12 +1526,10 @@ pub trait Iterator {
     fn all<F>(&mut self, mut f: F) -> bool where
         Self: Sized, F: FnMut(Self::Item) -> bool
     {
-        for x in self {
-            if !f(x) {
-                return false;
-            }
-        }
-        true
+        self.try_fold((), move |(), x| {
+            if f(x) { LoopState::Continue(()) }
+            else { LoopState::Break(()) }
+        }) == LoopState::Continue(())
     }
 
     /// Tests if any element of the iterator matches a predicate.
@@ -1506,12 +1575,10 @@ pub trait Iterator {
         Self: Sized,
         F: FnMut(Self::Item) -> bool
     {
-        for x in self {
-            if f(x) {
-                return true;
-            }
-        }
-        false
+        self.try_fold((), move |(), x| {
+            if f(x) { LoopState::Break(()) }
+            else { LoopState::Continue(()) }
+        }) == LoopState::Break(())
     }
 
     /// Searches for an element of an iterator that satisfies a predicate.
@@ -1562,10 +1629,10 @@ pub trait Iterator {
         Self: Sized,
         P: FnMut(&Self::Item) -> bool,
     {
-        for x in self {
-            if predicate(&x) { return Some(x) }
-        }
-        None
+        self.try_fold((), move |(), x| {
+            if predicate(&x) { LoopState::Break(x) }
+            else { LoopState::Continue(()) }
+        }).break_value()
     }
 
     /// Searches for an element in an iterator, returning its index.
@@ -1623,18 +1690,17 @@ pub trait Iterator {
     ///
     /// ```
     #[inline]
+    #[rustc_inherit_overflow_checks]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
         Self: Sized,
         P: FnMut(Self::Item) -> bool,
     {
-        // `enumerate` might overflow.
-        for (i, x) in self.enumerate() {
-            if predicate(x) {
-                return Some(i);
-            }
-        }
-        None
+        // The addition might panic on overflow
+        self.try_fold(0, move |i, x| {
+            if predicate(x) { LoopState::Break(i) }
+            else { LoopState::Continue(i + 1) }
+        }).break_value()
     }
 
     /// Searches for an element in an iterator from the right, returning its
@@ -1681,17 +1747,14 @@ pub trait Iterator {
         P: FnMut(Self::Item) -> bool,
         Self: Sized + ExactSizeIterator + DoubleEndedIterator
     {
-        let mut i = self.len();
-
-        while let Some(v) = self.next_back() {
-            // No need for an overflow check here, because `ExactSizeIterator`
-            // implies that the number of elements fits into a `usize`.
-            i -= 1;
-            if predicate(v) {
-                return Some(i);
-            }
-        }
-        None
+        // No need for an overflow check here, because `ExactSizeIterator`
+        // implies that the number of elements fits into a `usize`.
+        let n = self.len();
+        self.try_rfold(n, move |i, x| {
+            let i = i - 1;
+            if predicate(x) { LoopState::Break(i) }
+            else { LoopState::Continue(i) }
+        }).break_value()
     }
 
     /// Returns the maximum element of an iterator.
@@ -1922,10 +1985,10 @@ pub trait Iterator {
         let mut ts: FromA = Default::default();
         let mut us: FromB = Default::default();
 
-        for (t, u) in self {
+        self.for_each(|(t, u)| {
             ts.extend(Some(t));
             us.extend(Some(u));
-        }
+        });
 
         (ts, us)
     }
@@ -2059,14 +2122,23 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return Ordering::Equal,
-                (None, _   ) => return Ordering::Less,
-                (_   , None) => return Ordering::Greater,
-                (Some(x), Some(y)) => match x.cmp(&y) {
-                    Ordering::Equal => (),
-                    non_eq => return non_eq,
+            let x = match self.next() {
+                None => if other.next().is_none() {
+                    return Ordering::Equal
+                } else {
+                    return Ordering::Less
                 },
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return Ordering::Greater,
+                Some(val) => val,
+            };
+
+            match x.cmp(&y) {
+                Ordering::Equal => (),
+                non_eq => return non_eq,
             }
         }
     }
@@ -2082,14 +2154,23 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return Some(Ordering::Equal),
-                (None, _   ) => return Some(Ordering::Less),
-                (_   , None) => return Some(Ordering::Greater),
-                (Some(x), Some(y)) => match x.partial_cmp(&y) {
-                    Some(Ordering::Equal) => (),
-                    non_eq => return non_eq,
+            let x = match self.next() {
+                None => if other.next().is_none() {
+                    return Some(Ordering::Equal)
+                } else {
+                    return Some(Ordering::Less)
                 },
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return Some(Ordering::Greater),
+                Some(val) => val,
+            };
+
+            match x.partial_cmp(&y) {
+                Some(Ordering::Equal) => (),
+                non_eq => return non_eq,
             }
         }
     }
@@ -2105,11 +2186,17 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return true,
-                (None, _) | (_, None) => return false,
-                (Some(x), Some(y)) => if x != y { return false },
-            }
+            let x = match self.next() {
+                None => return other.next().is_none(),
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return false,
+                Some(val) => val,
+            };
+
+            if x != y { return false }
         }
     }
 
@@ -2124,11 +2211,17 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return false,
-                (None, _) | (_, None) => return true,
-                (Some(x), Some(y)) => if x.ne(&y) { return true },
-            }
+            let x = match self.next() {
+                None => return other.next().is_some(),
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return true,
+                Some(val) => val,
+            };
+
+            if x != y { return true }
         }
     }
 
@@ -2143,18 +2236,21 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return false,
-                (None, _   ) => return true,
-                (_   , None) => return false,
-                (Some(x), Some(y)) => {
-                    match x.partial_cmp(&y) {
-                        Some(Ordering::Less) => return true,
-                        Some(Ordering::Equal) => {}
-                        Some(Ordering::Greater) => return false,
-                        None => return false,
-                    }
-                },
+            let x = match self.next() {
+                None => return other.next().is_some(),
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return false,
+                Some(val) => val,
+            };
+
+            match x.partial_cmp(&y) {
+                Some(Ordering::Less) => return true,
+                Some(Ordering::Equal) => (),
+                Some(Ordering::Greater) => return false,
+                None => return false,
             }
         }
     }
@@ -2170,18 +2266,21 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return true,
-                (None, _   ) => return true,
-                (_   , None) => return false,
-                (Some(x), Some(y)) => {
-                    match x.partial_cmp(&y) {
-                        Some(Ordering::Less) => return true,
-                        Some(Ordering::Equal) => {}
-                        Some(Ordering::Greater) => return false,
-                        None => return false,
-                    }
-                },
+            let x = match self.next() {
+                None => { other.next(); return true; },
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return false,
+                Some(val) => val,
+            };
+
+            match x.partial_cmp(&y) {
+                Some(Ordering::Less) => return true,
+                Some(Ordering::Equal) => (),
+                Some(Ordering::Greater) => return false,
+                None => return false,
             }
         }
     }
@@ -2197,18 +2296,21 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return false,
-                (None, _   ) => return false,
-                (_   , None) => return true,
-                (Some(x), Some(y)) => {
-                    match x.partial_cmp(&y) {
-                        Some(Ordering::Less) => return false,
-                        Some(Ordering::Equal) => {}
-                        Some(Ordering::Greater) => return true,
-                        None => return false,
-                    }
-                }
+            let x = match self.next() {
+                None => { other.next(); return false; },
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return true,
+                Some(val) => val,
+            };
+
+            match x.partial_cmp(&y) {
+                Some(Ordering::Less) => return false,
+                Some(Ordering::Equal) => (),
+                Some(Ordering::Greater) => return true,
+                None => return false,
             }
         }
     }
@@ -2224,18 +2326,21 @@ pub trait Iterator {
         let mut other = other.into_iter();
 
         loop {
-            match (self.next(), other.next()) {
-                (None, None) => return true,
-                (None, _   ) => return false,
-                (_   , None) => return true,
-                (Some(x), Some(y)) => {
-                    match x.partial_cmp(&y) {
-                        Some(Ordering::Less) => return false,
-                        Some(Ordering::Equal) => {}
-                        Some(Ordering::Greater) => return true,
-                        None => return false,
-                    }
-                },
+            let x = match self.next() {
+                None => return other.next().is_none(),
+                Some(val) => val,
+            };
+
+            let y = match other.next() {
+                None => return true,
+                Some(val) => val,
+            };
+
+            match x.partial_cmp(&y) {
+                Some(Ordering::Less) => return false,
+                Some(Ordering::Equal) => (),
+                Some(Ordering::Greater) => return true,
+                None => return false,
             }
         }
     }
@@ -2258,17 +2363,17 @@ fn select_fold1<I, B, FProj, FCmp>(mut it: I,
     // start with the first element as our selection. This avoids
     // having to use `Option`s inside the loop, translating to a
     // sizeable performance gain (6x in one case).
-    it.next().map(|mut sel| {
-        let mut sel_p = f_proj(&sel);
+    it.next().map(|first| {
+        let first_p = f_proj(&first);
 
-        for x in it {
+        it.fold((first_p, first), |(sel_p, sel), x| {
             let x_p = f_proj(&x);
             if f_cmp(&sel_p, &sel, &x_p, &x) {
-                sel = x;
-                sel_p = x_p;
+                (x_p, x)
+            } else {
+                (sel_p, sel)
             }
-        }
-        (sel_p, sel)
+        })
     })
 }
 
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 2d3ff6a348d..e173f43b5e6 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -305,6 +305,7 @@
 use cmp;
 use fmt;
 use iter_private::TrustedRandomAccess;
+use ops::Try;
 use usize;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -336,6 +337,71 @@ mod range;
 mod sources;
 mod traits;
 
+/// Transparent newtype used to implement foo methods in terms of try_foo.
+/// Important until #43278 is fixed; might be better as `Result<T, !>` later.
+struct AlwaysOk<T>(pub T);
+
+impl<T> Try for AlwaysOk<T> {
+    type Ok = T;
+    type Error = !;
+    #[inline]
+    fn into_result(self) -> Result<Self::Ok, Self::Error> { Ok(self.0) }
+    #[inline]
+    fn from_error(v: Self::Error) -> Self { v }
+    #[inline]
+    fn from_ok(v: Self::Ok) -> Self { AlwaysOk(v) }
+}
+
+/// Used to make try_fold closures more like normal loops
+#[derive(PartialEq)]
+enum LoopState<C, B> {
+    Continue(C),
+    Break(B),
+}
+
+impl<C, B> Try for LoopState<C, B> {
+    type Ok = C;
+    type Error = B;
+    #[inline]
+    fn into_result(self) -> Result<Self::Ok, Self::Error> {
+        match self {
+            LoopState::Continue(y) => Ok(y),
+            LoopState::Break(x) => Err(x),
+        }
+    }
+    #[inline]
+    fn from_error(v: Self::Error) -> Self { LoopState::Break(v) }
+    #[inline]
+    fn from_ok(v: Self::Ok) -> Self { LoopState::Continue(v) }
+}
+
+impl<C, B> LoopState<C, B> {
+    #[inline]
+    fn break_value(self) -> Option<B> {
+        match self {
+            LoopState::Continue(..) => None,
+            LoopState::Break(x) => Some(x),
+        }
+    }
+}
+
+impl<R: Try> LoopState<R::Ok, R> {
+    #[inline]
+    fn from_try(r: R) -> Self {
+        match Try::into_result(r) {
+            Ok(v) => LoopState::Continue(v),
+            Err(v) => LoopState::Break(Try::from_error(v)),
+        }
+    }
+    #[inline]
+    fn into_try(self) -> R {
+        match self {
+            LoopState::Continue(v) => Try::from_ok(v),
+            LoopState::Break(v) => v,
+        }
+    }
+}
+
 /// A double-ended iterator with the direction inverted.
 ///
 /// This `struct` is created by the [`rev`] method on [`Iterator`]. See its
@@ -359,6 +425,12 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     #[inline]
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 
+    fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        self.iter.try_rfold(init, f)
+    }
+
     fn fold<Acc, F>(self, init: Acc, f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -385,6 +457,12 @@ impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
     #[inline]
     fn next_back(&mut self) -> Option<<I as Iterator>::Item> { self.iter.next() }
 
+    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        self.iter.try_fold(init, f)
+    }
+
     fn rfold<Acc, F>(self, init: Acc, f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -447,6 +525,12 @@ impl<'a, I, T: 'a> Iterator for Cloned<I>
         self.it.size_hint()
     }
 
+    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        self.it.try_fold(init, move |acc, elt| f(acc, elt.clone()))
+    }
+
     fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -462,6 +546,12 @@ impl<'a, I, T: 'a> DoubleEndedIterator for Cloned<I>
         self.it.next_back().cloned()
     }
 
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        self.it.try_rfold(init, move |acc, elt| f(acc, elt.clone()))
+    }
+
     fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -558,7 +648,7 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
 #[unstable(feature = "fused", issue = "35602")]
 impl<I> FusedIterator for Cycle<I> where I: Clone + Iterator {}
 
-/// An adapter for stepping iterators by a custom amount.
+/// An iterator for stepping iterators by a custom amount.
 ///
 /// This `struct` is created by the [`step_by`] method on [`Iterator`]. See
 /// its documentation for more.
@@ -683,6 +773,25 @@ impl<A, B> Iterator for Chain<A, B> where
         }
     }
 
+    fn try_fold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
+        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Front => {
+                accum = self.a.try_fold(accum, &mut f)?;
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Back;
+                }
+            }
+            _ => { }
+        }
+        if let ChainState::Back = self.state {
+            accum = self.b.try_fold(accum, &mut f)?;
+        }
+        Try::from_ok(accum)
+    }
+
     fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -792,6 +901,25 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
         }
     }
 
+    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R where
+        Self: Sized, F: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let mut accum = init;
+        match self.state {
+            ChainState::Both | ChainState::Back => {
+                accum = self.b.try_rfold(accum, &mut f)?;
+                if let ChainState::Both = self.state {
+                    self.state = ChainState::Front;
+                }
+            }
+            _ => { }
+        }
+        if let ChainState::Front = self.state {
+            accum = self.a.try_rfold(accum, &mut f)?;
+        }
+        Try::from_ok(accum)
+    }
+
     fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
         where F: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -1128,6 +1256,13 @@ impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
         self.iter.size_hint()
     }
 
+    fn try_fold<Acc, G, R>(&mut self, init: Acc, mut g: G) -> R where
+        Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let f = &mut self.f;
+        self.iter.try_fold(init, move |acc, elt| g(acc, f(elt)))
+    }
+
     fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
         where G: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -1145,6 +1280,13 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F> where
         self.iter.next_back().map(&mut self.f)
     }
 
+    fn try_rfold<Acc, G, R>(&mut self, init: Acc, mut g: G) -> R where
+        Self: Sized, G: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let f = &mut self.f;
+        self.iter.try_rfold(init, move |acc, elt| g(acc, f(elt)))
+    }
+
     fn rfold<Acc, G>(self, init: Acc, mut g: G) -> Acc
         where G: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -1250,6 +1392,30 @@ impl<I: Iterator, P> Iterator for Filter<I, P> where P: FnMut(&I::Item) -> bool
         }
         count
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let predicate = &mut self.predicate;
+        self.iter.try_fold(init, move |acc, item| if predicate(&item) {
+            fold(acc, item)
+        } else {
+            Try::from_ok(acc)
+        })
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut predicate = self.predicate;
+        self.iter.fold(init, move |acc, item| if predicate(&item) {
+            fold(acc, item)
+        } else {
+            acc
+        })
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1265,6 +1431,30 @@ impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>
         }
         None
     }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let predicate = &mut self.predicate;
+        self.iter.try_rfold(init, move |acc, item| if predicate(&item) {
+            fold(acc, item)
+        } else {
+            Try::from_ok(acc)
+        })
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut predicate = self.predicate;
+        self.iter.rfold(init, move |acc, item| if predicate(&item) {
+            fold(acc, item)
+        } else {
+            acc
+        })
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
@@ -1316,6 +1506,28 @@ impl<B, I: Iterator, F> Iterator for FilterMap<I, F>
         let (_, upper) = self.iter.size_hint();
         (0, upper) // can't know a lower bound, due to the predicate
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let f = &mut self.f;
+        self.iter.try_fold(init, move |acc, item| match f(item) {
+            Some(x) => fold(acc, x),
+            None => Try::from_ok(acc),
+        })
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter.fold(init, move |acc, item| match f(item) {
+            Some(x) => fold(acc, x),
+            None => acc,
+        })
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1331,6 +1543,28 @@ impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>
         }
         None
     }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let f = &mut self.f;
+        self.iter.try_rfold(init, move |acc, item| match f(item) {
+            Some(x) => fold(acc, x),
+            None => Try::from_ok(acc),
+        })
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter.rfold(init, move |acc, item| match f(item) {
+            Some(x) => fold(acc, x),
+            None => acc,
+        })
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
@@ -1395,6 +1629,32 @@ impl<I> Iterator for Enumerate<I> where I: Iterator {
     fn count(self) -> usize {
         self.iter.count()
     }
+
+    #[inline]
+    #[rustc_inherit_overflow_checks]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let count = &mut self.count;
+        self.iter.try_fold(init, move |acc, item| {
+            let acc = fold(acc, (*count, item));
+            *count += 1;
+            acc
+        })
+    }
+
+    #[inline]
+    #[rustc_inherit_overflow_checks]
+    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut count = self.count;
+        self.iter.fold(init, move |acc, item| {
+            let acc = fold(acc, (count, item));
+            count += 1;
+            acc
+        })
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1410,6 +1670,32 @@ impl<I> DoubleEndedIterator for Enumerate<I> where
             (self.count + len, a)
         })
     }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        // Can safely add and subtract the count, as `ExactSizeIterator` promises
+        // that the number of elements fits into a `usize`.
+        let mut count = self.count + self.iter.len();
+        self.iter.try_rfold(init, move |acc, item| {
+            count -= 1;
+            fold(acc, (count, item))
+        })
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        // Can safely add and subtract the count, as `ExactSizeIterator` promises
+        // that the number of elements fits into a `usize`.
+        let mut count = self.count + self.iter.len();
+        self.iter.rfold(init, move |acc, item| {
+            count -= 1;
+            fold(acc, (count, item))
+        })
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1521,6 +1807,30 @@ impl<I: Iterator> Iterator for Peekable<I> {
         let hi = hi.and_then(|x| x.checked_add(peek_len));
         (lo, hi)
     }
+
+    #[inline]
+    fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        let acc = match self.peeked.take() {
+            Some(None) => return Try::from_ok(init),
+            Some(Some(v)) => f(init, v)?,
+            None => init,
+        };
+        self.iter.try_fold(acc, f)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let acc = match self.peeked {
+            Some(None) => return init,
+            Some(Some(v)) => fold(init, v),
+            None => init,
+        };
+        self.iter.fold(acc, fold)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1615,13 +1925,16 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
 
     #[inline]
     fn next(&mut self) -> Option<I::Item> {
-        for x in self.iter.by_ref() {
-            if self.flag || !(self.predicate)(&x) {
-                self.flag = true;
-                return Some(x);
+        let flag = &mut self.flag;
+        let pred = &mut self.predicate;
+        self.iter.find(move |x| {
+            if *flag || !pred(x) {
+                *flag = true;
+                true
+            } else {
+                false
             }
-        }
-        None
+        })
     }
 
     #[inline]
@@ -1629,6 +1942,32 @@ impl<I: Iterator, P> Iterator for SkipWhile<I, P>
         let (_, upper) = self.iter.size_hint();
         (0, upper) // can't know a lower bound, due to the predicate
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if !self.flag {
+            match self.next() {
+                Some(v) => init = fold(init, v)?,
+                None => return Try::from_ok(init),
+            }
+        }
+        self.iter.try_fold(init, fold)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(mut self, mut init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        if !self.flag {
+            match self.next() {
+                Some(v) => init = fold(init, v),
+                None => return init,
+            }
+        }
+        self.iter.fold(init, fold)
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
@@ -1688,6 +2027,26 @@ impl<I: Iterator, P> Iterator for TakeWhile<I, P>
         let (_, upper) = self.iter.size_hint();
         (0, upper) // can't know a lower bound, due to the predicate
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if self.flag {
+            Try::from_ok(init)
+        } else {
+            let flag = &mut self.flag;
+            let p = &mut self.predicate;
+            self.iter.try_fold(init, move |acc, x|{
+                if p(&x) {
+                    LoopState::from_try(fold(acc, x))
+                } else {
+                    *flag = true;
+                    LoopState::Break(Try::from_ok(acc))
+                }
+            }).into_try()
+        }
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
@@ -1769,6 +2128,34 @@ impl<I> Iterator for Skip<I> where I: Iterator {
 
         (lower, upper)
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let n = self.n;
+        self.n = 0;
+        if n > 0 {
+            // nth(n) skips n+1
+            if self.iter.nth(n - 1).is_none() {
+                return Try::from_ok(init);
+            }
+        }
+        self.iter.try_fold(init, fold)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        if self.n > 0 {
+            // nth(n) skips n+1
+            if self.iter.nth(self.n - 1).is_none() {
+                return init;
+            }
+        }
+        self.iter.fold(init, fold)
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1783,6 +2170,22 @@ impl<I> DoubleEndedIterator for Skip<I> where I: DoubleEndedIterator + ExactSize
             None
         }
     }
+
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let mut n = self.len();
+        if n == 0 {
+            Try::from_ok(init)
+        } else {
+            self.iter.try_rfold(init, move |acc, x| {
+                n -= 1;
+                let r = fold(acc, x);
+                if n == 0 { LoopState::Break(r) }
+                else { LoopState::from_try(r) }
+            }).into_try()
+        }
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
@@ -1844,6 +2247,23 @@ impl<I> Iterator for Take<I> where I: Iterator{
 
         (lower, upper)
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if self.n == 0 {
+            Try::from_ok(init)
+        } else {
+            let n = &mut self.n;
+            self.iter.try_fold(init, move |acc, x| {
+                *n -= 1;
+                let r = fold(acc, x);
+                if *n == 0 { LoopState::Break(r) }
+                else { LoopState::from_try(r) }
+            }).into_try()
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1895,6 +2315,20 @@ impl<B, I, St, F> Iterator for Scan<I, St, F> where
         let (_, upper) = self.iter.size_hint();
         (0, upper) // can't know a lower bound, due to the scan function
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let state = &mut self.state;
+        let f = &mut self.f;
+        self.iter.try_fold(init, move |acc, x| {
+            match f(state, x) {
+                None => LoopState::Break(Try::from_ok(acc)),
+                Some(x) => LoopState::from_try(fold(acc, x)),
+            }
+        }).into_try()
+    }
 }
 
 /// An iterator that maps each element to an iterator, and yields the elements
@@ -1961,6 +2395,35 @@ impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
     }
 
     #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if let Some(ref mut front) = self.frontiter {
+            init = front.try_fold(init, &mut fold)?;
+        }
+        self.frontiter = None;
+
+        {
+            let f = &mut self.f;
+            let frontiter = &mut self.frontiter;
+            init = self.iter.try_fold(init, |acc, x| {
+                let mut mid = f(x).into_iter();
+                let r = mid.try_fold(acc, &mut fold);
+                *frontiter = Some(mid);
+                r
+            })?;
+        }
+        self.frontiter = None;
+
+        if let Some(ref mut back) = self.backiter {
+            init = back.try_fold(init, &mut fold)?;
+        }
+        self.backiter = None;
+
+        Try::from_ok(init)
+    }
+
+    #[inline]
     fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
@@ -1991,6 +2454,45 @@ impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F> wher
             }
         }
     }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if let Some(ref mut back) = self.backiter {
+            init = back.try_rfold(init, &mut fold)?;
+        }
+        self.backiter = None;
+
+        {
+            let f = &mut self.f;
+            let backiter = &mut self.backiter;
+            init = self.iter.try_rfold(init, |acc, x| {
+                let mut mid = f(x).into_iter();
+                let r = mid.try_rfold(acc, &mut fold);
+                *backiter = Some(mid);
+                r
+            })?;
+        }
+        self.backiter = None;
+
+        if let Some(ref mut front) = self.frontiter {
+            init = front.try_rfold(init, &mut fold)?;
+        }
+        self.frontiter = None;
+
+        Try::from_ok(init)
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.frontiter.into_iter()
+            .chain(self.iter.map(self.f).map(U::into_iter))
+            .chain(self.backiter)
+            .rfold(init, |acc, iter| iter.rfold(acc, &mut fold))
+    }
 }
 
 #[unstable(feature = "fused", issue = "35602")]
@@ -2068,6 +2570,30 @@ impl<I> Iterator for Fuse<I> where I: Iterator {
             self.iter.size_hint()
         }
     }
+
+    #[inline]
+    default fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if self.done {
+            Try::from_ok(init)
+        } else {
+            let acc = self.iter.try_fold(init, fold)?;
+            self.done = true;
+            Try::from_ok(acc)
+        }
+    }
+
+    #[inline]
+    default fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        if self.done {
+            init
+        } else {
+            self.iter.fold(init, fold)
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2082,6 +2608,30 @@ impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
             next
         }
     }
+
+    #[inline]
+    default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        if self.done {
+            Try::from_ok(init)
+        } else {
+            let acc = self.iter.try_rfold(init, fold)?;
+            self.done = true;
+            Try::from_ok(acc)
+        }
+    }
+
+    #[inline]
+    default fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        if self.done {
+            init
+        } else {
+            self.iter.rfold(init, fold)
+        }
+    }
 }
 
 unsafe impl<I> TrustedRandomAccess for Fuse<I>
@@ -2122,6 +2672,20 @@ impl<I> Iterator for Fuse<I> where I: FusedIterator {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        self.iter.try_fold(init, fold)
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.iter.fold(init, fold)
+    }
 }
 
 #[unstable(feature = "fused", reason = "recently added", issue = "35602")]
@@ -2132,6 +2696,20 @@ impl<I> DoubleEndedIterator for Fuse<I>
     fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
         self.iter.next_back()
     }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        self.iter.try_rfold(init, fold)
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        self.iter.rfold(init, fold)
+    }
 }
 
 
@@ -2196,6 +2774,22 @@ impl<I: Iterator, F> Iterator for Inspect<I, F> where F: FnMut(&I::Item) {
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()
     }
+
+    #[inline]
+    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let f = &mut self.f;
+        self.iter.try_fold(init, move |acc, item| { f(&item); fold(acc, item) })
+    }
+
+    #[inline]
+    fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter.fold(init, move |acc, item| { f(&item); fold(acc, item) })
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2207,6 +2801,22 @@ impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>
         let next = self.iter.next_back();
         self.do_inspect(next)
     }
+
+    #[inline]
+    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R where
+        Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok=Acc>
+    {
+        let f = &mut self.f;
+        self.iter.try_rfold(init, move |acc, item| { f(&item); fold(acc, item) })
+    }
+
+    #[inline]
+    fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
+        where Fold: FnMut(Acc, Self::Item) -> Acc,
+    {
+        let mut f = self.f;
+        self.iter.rfold(init, move |acc, item| { f(&item); fold(acc, item) })
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 73d518b570a..e9aee4a4676 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -89,6 +89,7 @@ macro_rules! step_impl_unsigned {
             }
 
             #[inline]
+            #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
                 match <$t>::try_from(n) {
                     Ok(n_as_t) => self.checked_add(n_as_t),
@@ -120,6 +121,7 @@ macro_rules! step_impl_signed {
             }
 
             #[inline]
+            #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
                 match <$unsigned>::try_from(n) {
                     Ok(n_as_unsigned) => {
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 28236d193c3..11e668d228c 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -7,9 +7,11 @@
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
-use ops::{Mul, Add};
+use ops::{Mul, Add, Try};
 use num::Wrapping;
 
+use super::{AlwaysOk, LoopState};
+
 /// Conversion from an `Iterator`.
 ///
 /// By implementing `FromIterator` for a type, you define how it will be
@@ -415,6 +417,52 @@ pub trait DoubleEndedIterator: Iterator {
     #[stable(feature = "rust1", since = "1.0.0")]
     fn next_back(&mut self) -> Option<Self::Item>;
 
+    /// This is the reverse version of [`try_fold()`]: it takes elements
+    /// starting from the back of the iterator.
+    ///
+    /// [`try_fold()`]: trait.Iterator.html#method.try_fold
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(iterator_try_fold)]
+    /// let a = ["1", "2", "3"];
+    /// let sum = a.iter()
+    ///     .map(|&s| s.parse::<i32>())
+    ///     .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
+    /// assert_eq!(sum, Ok(6));
+    /// ```
+    ///
+    /// Short-circuiting:
+    ///
+    /// ```
+    /// #![feature(iterator_try_fold)]
+    /// let a = ["1", "rust", "3"];
+    /// let mut it = a.iter();
+    /// let sum = it
+    ///     .by_ref()
+    ///     .map(|&s| s.parse::<i32>())
+    ///     .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
+    /// assert!(sum.is_err());
+    ///
+    /// // Because it short-circuited, the remaining elements are still
+    /// // available through the iterator.
+    /// assert_eq!(it.next_back(), Some(&"1"));
+    /// ```
+    #[inline]
+    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+        Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
+    {
+        let mut accum = init;
+        while let Some(x) = self.next_back() {
+            accum = f(accum, x)?;
+        }
+        Try::from_ok(accum)
+    }
+
     /// An iterator method that reduces the iterator's elements to a single,
     /// final value, starting from the back.
     ///
@@ -470,13 +518,10 @@ pub trait DoubleEndedIterator: Iterator {
     /// ```
     #[inline]
     #[unstable(feature = "iter_rfold", issue = "44705")]
-    fn rfold<B, F>(mut self, mut accum: B, mut f: F) -> B where
+    fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
-        while let Some(x) = self.next_back() {
-            accum = f(accum, x);
-        }
-        accum
+        self.try_rfold(accum, move |acc, x| AlwaysOk(f(acc, x))).0
     }
 
     /// Searches for an element of an iterator from the right that satisfies a predicate.
@@ -531,10 +576,10 @@ pub trait DoubleEndedIterator: Iterator {
         Self: Sized,
         P: FnMut(&Self::Item) -> bool
     {
-        while let Some(x) = self.next_back() {
-            if predicate(&x) { return Some(x) }
-        }
-        None
+        self.try_rfold((), move |(), x| {
+            if predicate(&x) { LoopState::Break(x) }
+            else { LoopState::Continue(()) }
+        }).break_value()
     }
 }
 
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 69612bd2a32..d5190b65863 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -85,29 +85,12 @@
 #![feature(prelude_import)]
 #![feature(repr_simd, platform_intrinsics)]
 #![feature(rustc_attrs)]
-#![cfg_attr(not(stage0), feature(rustc_const_unstable))]
 #![feature(specialization)]
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(untagged_unions)]
 #![feature(unwind_attributes)]
-
-#![cfg_attr(not(stage0), feature(const_min_value))]
-#![cfg_attr(not(stage0), feature(const_max_value))]
-#![cfg_attr(not(stage0), feature(const_atomic_bool_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_isize_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_usize_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_i8_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_u8_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_i16_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_u16_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_i32_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_u32_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_i64_new))]
-#![cfg_attr(not(stage0), feature(const_atomic_u64_new))]
-#![cfg_attr(not(stage0), feature(const_unsafe_cell_new))]
-#![cfg_attr(not(stage0), feature(const_cell_new))]
-#![cfg_attr(not(stage0), feature(const_nonzero_new))]
+#![feature(doc_spotlight)]
 
 #[prelude_import]
 #[allow(unused)]
@@ -190,3 +173,4 @@ pub mod fmt;
 mod char_private;
 mod iter_private;
 mod tuple;
+mod unit;
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index d64c984ea7d..6e3dbcbec9d 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -120,6 +120,9 @@ macro_rules! assert_eq {
             }
         }
     });
+    ($left:expr, $right:expr,) => ({
+        assert_eq!($left, $right)
+    });
     ($left:expr, $right:expr, $($arg:tt)+) => ({
         match (&($left), &($right)) {
             (left_val, right_val) => {
@@ -168,6 +171,9 @@ macro_rules! assert_ne {
             }
         }
     });
+    ($left:expr, $right:expr,) => {
+        assert_ne!($left, $right)
+    };
     ($left:expr, $right:expr, $($arg:tt)+) => ({
         match (&($left), &($right)) {
             (left_val, right_val) => {
@@ -355,7 +361,7 @@ macro_rules! try {
     })
 }
 
-/// Write formatted data into a buffer
+/// Write formatted data into a buffer.
 ///
 /// This macro accepts a format string, a list of arguments, and a 'writer'. Arguments will be
 /// formatted according to the specified format string and the result will be passed to the writer.
@@ -606,9 +612,10 @@ mod builtin {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[macro_export]
     #[cfg(dox)]
-    macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
-        /* compiler built-in */
-    }) }
+    macro_rules! format_args {
+        ($fmt:expr) => ({ /* compiler built-in */ });
+        ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ });
+    }
 
     /// Inspect an environment variable at compile time.
     ///
@@ -618,7 +625,10 @@ mod builtin {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[macro_export]
     #[cfg(dox)]
-    macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }
+    macro_rules! env {
+        ($name:expr) => ({ /* compiler built-in */ });
+        ($name:expr,) => ({ /* compiler built-in */ });
+    }
 
     /// Optionally inspect an environment variable at compile time.
     ///
@@ -639,7 +649,8 @@ mod builtin {
     #[macro_export]
     #[cfg(dox)]
     macro_rules! concat_idents {
-        ($($e:ident),*) => ({ /* compiler built-in */ })
+        ($($e:ident),*) => ({ /* compiler built-in */ });
+        ($($e:ident,)*) => ({ /* compiler built-in */ });
     }
 
     /// Concatenates literals into a static string slice.
@@ -650,7 +661,10 @@ mod builtin {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[macro_export]
     #[cfg(dox)]
-    macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }
+    macro_rules! concat {
+        ($($e:expr),*) => ({ /* compiler built-in */ });
+        ($($e:expr,)*) => ({ /* compiler built-in */ });
+    }
 
     /// A macro which expands to the line number on which it was invoked.
     ///
@@ -682,7 +696,7 @@ mod builtin {
     #[cfg(dox)]
     macro_rules! file { () => ({ /* compiler built-in */ }) }
 
-    /// A macro which stringifies its argument.
+    /// A macro which stringifies its arguments.
     ///
     /// For more information, see the documentation for [`std::stringify!`].
     ///
@@ -690,7 +704,7 @@ mod builtin {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[macro_export]
     #[cfg(dox)]
-    macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }
+    macro_rules! stringify { ($($t:tt)*) => ({ /* compiler built-in */ }) }
 
     /// Includes a utf8-encoded file as a string.
     ///
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index e8fd729b638..17e77654cf5 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -39,13 +39,14 @@ use hash::Hasher;
 /// [arc]: ../../std/sync/struct.Arc.html
 /// [ub]: ../../reference/behavior-considered-undefined.html
 #[stable(feature = "rust1", since = "1.0.0")]
-#[lang = "send"]
 #[rustc_on_unimplemented = "`{Self}` cannot be sent between threads safely"]
 pub unsafe trait Send {
     // empty.
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 unsafe impl Send for .. { }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -122,7 +123,7 @@ pub trait Sized {
 /// [RFC982]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 /// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "unsize", issue = "27732")]
-#[lang="unsize"]
+#[lang = "unsize"]
 pub trait Unsize<T: ?Sized> {
     // Empty.
 }
@@ -312,7 +313,7 @@ pub trait Copy : Clone {
 ///
 /// For cases when one does need thread-safe interior mutability,
 /// Rust provides [atomic data types], as well as explicit locking via
-/// [`sync::Mutex`][mutex] and [`sync::RWLock`][rwlock]. These types
+/// [`sync::Mutex`][mutex] and [`sync::RwLock`][rwlock]. These types
 /// ensure that any mutation cannot cause data races, hence the types
 /// are `Sync`. Likewise, [`sync::Arc`][arc] provides a thread-safe
 /// analogue of [`Rc`][rc].
@@ -349,6 +350,8 @@ pub unsafe trait Sync {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 unsafe impl Sync for .. { }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -562,6 +565,8 @@ mod impls {
 #[lang = "freeze"]
 unsafe trait Freeze {}
 
+#[allow(unknown_lints)]
+#[allow(auto_impl)]
 unsafe impl Freeze for .. {}
 
 impl<T: ?Sized> !Freeze for UnsafeCell<T> {}
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 669b93120cf..5b1a9399c39 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -209,6 +209,35 @@ pub fn forget<T>(t: T) {
 /// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
 /// have the same size. Likewise for `*const T` and `*mut T`.
 ///
+/// # Size of `#[repr(C)]` items
+///
+/// The `C` representation for items has a defined layout. With this layout,
+/// the size of items is also stable as long as all fields have a stable size.
+///
+/// ## Size of Structs
+///
+/// For `structs`, the size is determined by the following algorithm.
+///
+/// For each field in the struct ordered by declaration order:
+///
+/// 1. Add the size of the field.
+/// 2. Round up the current size to the nearest multiple of the next field's [alignment].
+///
+/// Finally, round the size of the struct to the nearest multiple of its [alignment].
+///
+/// Unlike `C`, zero sized structs are not rounded up to one byte in size.
+///
+/// ## Size of Enums
+///
+/// Enums that carry no data other than the descriminant have the same size as C enums
+/// on the platform they are compiled for.
+///
+/// ## Size of Unions
+///
+/// The size of a union is the size of its largest field.
+///
+/// Unlike `C`, zero sized unions are not rounded up to one byte in size.
+///
 /// # Examples
 ///
 /// ```
@@ -231,9 +260,57 @@ pub fn forget<T>(t: T) {
 /// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
 /// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
 /// ```
+///
+/// Using `#[repr(C)]`.
+///
+/// ```
+/// use std::mem;
+///
+/// #[repr(C)]
+/// struct FieldStruct {
+///     first: u8,
+///     second: u16,
+///     third: u8
+/// }
+///
+/// // The size of the first field is 1, so add 1 to the size. Size is 1.
+/// // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2.
+/// // The size of the second field is 2, so add 2 to the size. Size is 4.
+/// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4.
+/// // The size of the third field is 1, so add 1 to the size. Size is 5.
+/// // Finally, the alignment of the struct is 2, so add 1 to the size for padding. Size is 6.
+/// assert_eq!(6, mem::size_of::<FieldStruct>());
+///
+/// #[repr(C)]
+/// struct TupleStruct(u8, u16, u8);
+///
+/// // Tuple structs follow the same rules.
+/// assert_eq!(6, mem::size_of::<TupleStruct>());
+///
+/// // Note that reordering the fields can lower the size. We can remove both padding bytes
+/// // by putting `third` before `second`.
+/// #[repr(C)]
+/// struct FieldStructOptimized {
+///     first: u8,
+///     third: u8,
+///     second: u16
+/// }
+///
+/// assert_eq!(4, mem::size_of::<FieldStructOptimized>());
+///
+/// // Union size is the size of the largest field.
+/// #[repr(C)]
+/// union ExampleUnion {
+///     smaller: u8,
+///     larger: u16
+/// }
+///
+/// assert_eq!(2, mem::size_of::<ExampleUnion>());
+/// ```
+///
+/// [alignment]: ./fn.align_of.html
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_size_of"))]
 pub const fn size_of<T>() -> usize {
     unsafe { intrinsics::size_of::<T>() }
 }
@@ -325,7 +402,6 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_align_of"))]
 pub const fn align_of<T>() -> usize {
     unsafe { intrinsics::min_align_of::<T>() }
 }
@@ -351,9 +427,11 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
 
 /// Returns whether dropping values of type `T` matters.
 ///
-/// This is purely an optimization hint, and may be implemented conservatively.
-/// For instance, always returning `true` would be a valid implementation of
-/// this function.
+/// This is purely an optimization hint, and may be implemented conservatively:
+/// it may return `true` for types that don't actually need to be dropped.
+/// As such always returning `true` would be a valid implementation of
+/// this function. However if this function actually returns `false`, then you
+/// can be certain dropping `T` has no side effect.
 ///
 /// Low level implementations of things like collections, which need to manually
 /// drop their data, should use this function to avoid unnecessarily
@@ -402,7 +480,7 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
 /// }
 /// ```
 #[inline]
-#[stable(feature = "needs_drop", since = "1.22.0")]
+#[stable(feature = "needs_drop", since = "1.21.0")]
 pub fn needs_drop<T>() -> bool {
     unsafe { intrinsics::needs_drop::<T>() }
 }
@@ -758,7 +836,7 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
 ///
 /// See the `discriminant` function in this module for more information.
 #[stable(feature = "discriminant_value", since = "1.21.0")]
-pub struct Discriminant<T>(u64, PhantomData<*const T>);
+pub struct Discriminant<T>(u64, PhantomData<fn() -> T>);
 
 // N.B. These trait implementations cannot be derived because we don't want any bounds on T.
 
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index f075d825f5d..2c966eb3b57 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -28,8 +28,7 @@ macro_rules! impl_zeroable_for_pointer_types {
             unsafe impl<T: ?Sized> Zeroable for $Ptr {
                 #[inline]
                 fn is_zero(&self) -> bool {
-                    // Cast because `is_null` is only available on thin pointers
-                    (*self as *mut u8).is_null()
+                    (*self).is_null()
                 }
             }
         )+
@@ -71,7 +70,6 @@ impl<T: Zeroable> NonZero<T> {
     #[unstable(feature = "nonzero",
                reason = "needs an RFC to flesh out the design",
                issue = "27730")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_nonzero_new"))]
     #[inline]
     pub const unsafe fn new_unchecked(inner: T) -> Self {
         NonZero(inner)
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index bf31deae7a6..7c7562eac51 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -12,9 +12,10 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use convert::TryFrom;
+use convert::{Infallible, TryFrom};
 use fmt;
 use intrinsics;
+use ops;
 use str::FromStr;
 
 /// Provides intentionally-wrapped arithmetic on `T`.
@@ -109,7 +110,6 @@ macro_rules! int_impl {
         /// assert_eq!(i8::min_value(), -128);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_min_value"))]
         #[inline]
         pub const fn min_value() -> Self {
             !0 ^ ((!0 as $UnsignedT) >> 1) as Self
@@ -123,7 +123,6 @@ macro_rules! int_impl {
         /// assert_eq!(i8::max_value(), 127);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_max_value"))]
         #[inline]
         pub const fn max_value() -> Self {
             !Self::min_value()
@@ -131,7 +130,14 @@ macro_rules! int_impl {
 
         /// Converts a string slice in a given base to an integer.
         ///
+        /// The string is expected to be an optional `+` or `-` sign
+        /// followed by digits.
         /// Leading and trailing whitespace represent an error.
+        /// Digits are a subset of these characters, depending on `radix`:
+        ///
+        /// * `0-9`
+        /// * `a-z`
+        /// * `A-Z`
         ///
         /// # Panics
         ///
@@ -374,7 +380,7 @@ macro_rules! int_impl {
             if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
         }
 
-        /// Checked integer addition. Computes `self + other`, returning `None`
+        /// Checked integer addition. Computes `self + rhs`, returning `None`
         /// if overflow occurred.
         ///
         /// # Examples
@@ -387,12 +393,12 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_add(self, other: Self) -> Option<Self> {
-            let (a, b) = self.overflowing_add(other);
+        pub fn checked_add(self, rhs: Self) -> Option<Self> {
+            let (a, b) = self.overflowing_add(rhs);
             if b {None} else {Some(a)}
         }
 
-        /// Checked integer subtraction. Computes `self - other`, returning
+        /// Checked integer subtraction. Computes `self - rhs`, returning
         /// `None` if underflow occurred.
         ///
         /// # Examples
@@ -405,12 +411,12 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_sub(self, other: Self) -> Option<Self> {
-            let (a, b) = self.overflowing_sub(other);
+        pub fn checked_sub(self, rhs: Self) -> Option<Self> {
+            let (a, b) = self.overflowing_sub(rhs);
             if b {None} else {Some(a)}
         }
 
-        /// Checked integer multiplication. Computes `self * other`, returning
+        /// Checked integer multiplication. Computes `self * rhs`, returning
         /// `None` if underflow or overflow occurred.
         ///
         /// # Examples
@@ -423,13 +429,13 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_mul(self, other: Self) -> Option<Self> {
-            let (a, b) = self.overflowing_mul(other);
+        pub fn checked_mul(self, rhs: Self) -> Option<Self> {
+            let (a, b) = self.overflowing_mul(rhs);
             if b {None} else {Some(a)}
         }
 
-        /// Checked integer division. Computes `self / other`, returning `None`
-        /// if `other == 0` or the operation results in underflow or overflow.
+        /// Checked integer division. Computes `self / rhs`, returning `None`
+        /// if `rhs == 0` or the operation results in underflow or overflow.
         ///
         /// # Examples
         ///
@@ -442,16 +448,16 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_div(self, other: Self) -> Option<Self> {
-            if other == 0 || (self == Self::min_value() && other == -1) {
+        pub fn checked_div(self, rhs: Self) -> Option<Self> {
+            if rhs == 0 || (self == Self::min_value() && rhs == -1) {
                 None
             } else {
-                Some(unsafe { intrinsics::unchecked_div(self, other) })
+                Some(unsafe { intrinsics::unchecked_div(self, rhs) })
             }
         }
 
-        /// Checked integer remainder. Computes `self % other`, returning `None`
-        /// if `other == 0` or the operation results in underflow or overflow.
+        /// Checked integer remainder. Computes `self % rhs`, returning `None`
+        /// if `rhs == 0` or the operation results in underflow or overflow.
         ///
         /// # Examples
         ///
@@ -466,11 +472,11 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[inline]
-        pub fn checked_rem(self, other: Self) -> Option<Self> {
-            if other == 0 || (self == Self::min_value() && other == -1) {
+        pub fn checked_rem(self, rhs: Self) -> Option<Self> {
+            if rhs == 0 || (self == Self::min_value() && rhs == -1) {
                 None
             } else {
-                Some(unsafe { intrinsics::unchecked_rem(self, other) })
+                Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
             }
         }
 
@@ -553,7 +559,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Saturating integer addition. Computes `self + other`, saturating at
+        /// Saturating integer addition. Computes `self + rhs`, saturating at
         /// the numeric bounds instead of overflowing.
         ///
         /// # Examples
@@ -566,15 +572,15 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn saturating_add(self, other: Self) -> Self {
-            match self.checked_add(other) {
+        pub fn saturating_add(self, rhs: Self) -> Self {
+            match self.checked_add(rhs) {
                 Some(x) => x,
-                None if other >= 0 => Self::max_value(),
+                None if rhs >= 0 => Self::max_value(),
                 None => Self::min_value(),
             }
         }
 
-        /// Saturating integer subtraction. Computes `self - other`, saturating
+        /// Saturating integer subtraction. Computes `self - rhs`, saturating
         /// at the numeric bounds instead of overflowing.
         ///
         /// # Examples
@@ -587,15 +593,15 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn saturating_sub(self, other: Self) -> Self {
-            match self.checked_sub(other) {
+        pub fn saturating_sub(self, rhs: Self) -> Self {
+            match self.checked_sub(rhs) {
                 Some(x) => x,
-                None if other >= 0 => Self::min_value(),
+                None if rhs >= 0 => Self::min_value(),
                 None => Self::max_value(),
             }
         }
 
-        /// Saturating integer multiplication. Computes `self * other`,
+        /// Saturating integer multiplication. Computes `self * rhs`,
         /// saturating at the numeric bounds instead of overflowing.
         ///
         /// # Examples
@@ -611,9 +617,9 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[inline]
-        pub fn saturating_mul(self, other: Self) -> Self {
-            self.checked_mul(other).unwrap_or_else(|| {
-                if (self < 0 && other < 0) || (self > 0 && other > 0) {
+        pub fn saturating_mul(self, rhs: Self) -> Self {
+            self.checked_mul(rhs).unwrap_or_else(|| {
+                if (self < 0 && rhs < 0) || (self > 0 && rhs > 0) {
                     Self::max_value()
                 } else {
                     Self::min_value()
@@ -621,7 +627,7 @@ macro_rules! int_impl {
             })
         }
 
-        /// Wrapping (modular) addition. Computes `self + other`,
+        /// Wrapping (modular) addition. Computes `self + rhs`,
         /// wrapping around at the boundary of the type.
         ///
         /// # Examples
@@ -640,7 +646,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Wrapping (modular) subtraction. Computes `self - other`,
+        /// Wrapping (modular) subtraction. Computes `self - rhs`,
         /// wrapping around at the boundary of the type.
         ///
         /// # Examples
@@ -660,7 +666,7 @@ macro_rules! int_impl {
         }
 
         /// Wrapping (modular) multiplication. Computes `self *
-        /// other`, wrapping around at the boundary of the type.
+        /// rhs`, wrapping around at the boundary of the type.
         ///
         /// # Examples
         ///
@@ -678,7 +684,7 @@ macro_rules! int_impl {
             }
         }
 
-        /// Wrapping (modular) division. Computes `self / other`,
+        /// Wrapping (modular) division. Computes `self / rhs`,
         /// wrapping around at the boundary of the type.
         ///
         /// The only case where such wrapping can occur is when one
@@ -706,7 +712,7 @@ macro_rules! int_impl {
             self.overflowing_div(rhs).0
         }
 
-        /// Wrapping (modular) remainder. Computes `self % other`,
+        /// Wrapping (modular) remainder. Computes `self % rhs`,
         /// wrapping around at the boundary of the type.
         ///
         /// Such wrap-around never actually occurs mathematically;
@@ -1282,7 +1288,6 @@ macro_rules! uint_impl {
         /// assert_eq!(u8::min_value(), 0);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_min_value"))]
         #[inline]
         pub const fn min_value() -> Self { 0 }
 
@@ -1294,13 +1299,23 @@ macro_rules! uint_impl {
         /// assert_eq!(u8::max_value(), 255);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
-        #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_max_value"))]
         #[inline]
         pub const fn max_value() -> Self { !0 }
 
         /// Converts a string slice in a given base to an integer.
         ///
+        /// The string is expected to be an optional `+` sign
+        /// followed by digits.
         /// Leading and trailing whitespace represent an error.
+        /// Digits are a subset of these characters, depending on `radix`:
+        ///
+        /// * `0-9`
+        /// * `a-z`
+        /// * `A-Z`
+        ///
+        /// # Panics
+        ///
+        /// This function panics if `radix` is not in the range from 2 to 36.
         ///
         /// # Examples
         ///
@@ -1558,7 +1573,7 @@ macro_rules! uint_impl {
             if cfg!(target_endian = "little") { self } else { self.swap_bytes() }
         }
 
-        /// Checked integer addition. Computes `self + other`, returning `None`
+        /// Checked integer addition. Computes `self + rhs`, returning `None`
         /// if overflow occurred.
         ///
         /// # Examples
@@ -1571,12 +1586,12 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_add(self, other: Self) -> Option<Self> {
-            let (a, b) = self.overflowing_add(other);
+        pub fn checked_add(self, rhs: Self) -> Option<Self> {
+            let (a, b) = self.overflowing_add(rhs);
             if b {None} else {Some(a)}
         }
 
-        /// Checked integer subtraction. Computes `self - other`, returning
+        /// Checked integer subtraction. Computes `self - rhs`, returning
         /// `None` if underflow occurred.
         ///
         /// # Examples
@@ -1589,12 +1604,12 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_sub(self, other: Self) -> Option<Self> {
-            let (a, b) = self.overflowing_sub(other);
+        pub fn checked_sub(self, rhs: Self) -> Option<Self> {
+            let (a, b) = self.overflowing_sub(rhs);
             if b {None} else {Some(a)}
         }
 
-        /// Checked integer multiplication. Computes `self * other`, returning
+        /// Checked integer multiplication. Computes `self * rhs`, returning
         /// `None` if underflow or overflow occurred.
         ///
         /// # Examples
@@ -1607,13 +1622,13 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_mul(self, other: Self) -> Option<Self> {
-            let (a, b) = self.overflowing_mul(other);
+        pub fn checked_mul(self, rhs: Self) -> Option<Self> {
+            let (a, b) = self.overflowing_mul(rhs);
             if b {None} else {Some(a)}
         }
 
-        /// Checked integer division. Computes `self / other`, returning `None`
-        /// if `other == 0` or the operation results in underflow or overflow.
+        /// Checked integer division. Computes `self / rhs`, returning `None`
+        /// if `rhs == 0` or the operation results in underflow or overflow.
         ///
         /// # Examples
         ///
@@ -1625,15 +1640,15 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn checked_div(self, other: Self) -> Option<Self> {
-            match other {
+        pub fn checked_div(self, rhs: Self) -> Option<Self> {
+            match rhs {
                 0 => None,
-                other => Some(unsafe { intrinsics::unchecked_div(self, other) }),
+                rhs => Some(unsafe { intrinsics::unchecked_div(self, rhs) }),
             }
         }
 
-        /// Checked integer remainder. Computes `self % other`, returning `None`
-        /// if `other == 0` or the operation results in underflow or overflow.
+        /// Checked integer remainder. Computes `self % rhs`, returning `None`
+        /// if `rhs == 0` or the operation results in underflow or overflow.
         ///
         /// # Examples
         ///
@@ -1645,11 +1660,11 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[inline]
-        pub fn checked_rem(self, other: Self) -> Option<Self> {
-            if other == 0 {
+        pub fn checked_rem(self, rhs: Self) -> Option<Self> {
+            if rhs == 0 {
                 None
             } else {
-                Some(unsafe { intrinsics::unchecked_rem(self, other) })
+                Some(unsafe { intrinsics::unchecked_rem(self, rhs) })
             }
         }
 
@@ -1709,7 +1724,7 @@ macro_rules! uint_impl {
             if b {None} else {Some(a)}
         }
 
-        /// Saturating integer addition. Computes `self + other`, saturating at
+        /// Saturating integer addition. Computes `self + rhs`, saturating at
         /// the numeric bounds instead of overflowing.
         ///
         /// # Examples
@@ -1722,14 +1737,14 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn saturating_add(self, other: Self) -> Self {
-            match self.checked_add(other) {
+        pub fn saturating_add(self, rhs: Self) -> Self {
+            match self.checked_add(rhs) {
                 Some(x) => x,
                 None => Self::max_value(),
             }
         }
 
-        /// Saturating integer subtraction. Computes `self - other`, saturating
+        /// Saturating integer subtraction. Computes `self - rhs`, saturating
         /// at the numeric bounds instead of overflowing.
         ///
         /// # Examples
@@ -1742,14 +1757,14 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn saturating_sub(self, other: Self) -> Self {
-            match self.checked_sub(other) {
+        pub fn saturating_sub(self, rhs: Self) -> Self {
+            match self.checked_sub(rhs) {
                 Some(x) => x,
                 None => Self::min_value(),
             }
         }
 
-        /// Saturating integer multiplication. Computes `self * other`,
+        /// Saturating integer multiplication. Computes `self * rhs`,
         /// saturating at the numeric bounds instead of overflowing.
         ///
         /// # Examples
@@ -1764,11 +1779,11 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[inline]
-        pub fn saturating_mul(self, other: Self) -> Self {
-            self.checked_mul(other).unwrap_or(Self::max_value())
+        pub fn saturating_mul(self, rhs: Self) -> Self {
+            self.checked_mul(rhs).unwrap_or(Self::max_value())
         }
 
-        /// Wrapping (modular) addition. Computes `self + other`,
+        /// Wrapping (modular) addition. Computes `self + rhs`,
         /// wrapping around at the boundary of the type.
         ///
         /// # Examples
@@ -1787,7 +1802,7 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Wrapping (modular) subtraction. Computes `self - other`,
+        /// Wrapping (modular) subtraction. Computes `self - rhs`,
         /// wrapping around at the boundary of the type.
         ///
         /// # Examples
@@ -1807,7 +1822,7 @@ macro_rules! uint_impl {
         }
 
         /// Wrapping (modular) multiplication. Computes `self *
-        /// other`, wrapping around at the boundary of the type.
+        /// rhs`, wrapping around at the boundary of the type.
         ///
         /// # Examples
         ///
@@ -1825,7 +1840,7 @@ macro_rules! uint_impl {
             }
         }
 
-        /// Wrapping (modular) division. Computes `self / other`.
+        /// Wrapping (modular) division. Computes `self / rhs`.
         /// Wrapped division on unsigned types is just normal division.
         /// There's no way wrapping could ever happen.
         /// This function exists, so that all operations
@@ -1844,7 +1859,7 @@ macro_rules! uint_impl {
             self / rhs
         }
 
-        /// Wrapping (modular) remainder. Computes `self % other`.
+        /// Wrapping (modular) remainder. Computes `self % rhs`.
         /// Wrapped remainder calculation on unsigned types is
         /// just the regular remainder calculation.
         /// There's no way wrapping could ever happen.
@@ -2223,7 +2238,8 @@ macro_rules! uint_impl {
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
         pub fn next_power_of_two(self) -> Self {
-            self.one_less_than_next_power_of_two() + 1
+            // Call the trait to get overflow checks
+            ops::Add::add(self.one_less_than_next_power_of_two(), 1)
         }
 
         /// Returns the smallest power of two greater than or equal to `n`. If
@@ -2257,6 +2273,547 @@ impl u8 {
         intrinsics::add_with_overflow,
         intrinsics::sub_with_overflow,
         intrinsics::mul_with_overflow }
+
+
+    /// Checks if the value is within the ASCII range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let ascii = 97u8;
+    /// let non_ascii = 150u8;
+    ///
+    /// assert!(ascii.is_ascii());
+    /// assert!(!non_ascii.is_ascii());
+    /// ```
+    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.21.0")]
+    #[inline]
+    pub fn is_ascii(&self) -> bool {
+        *self & 128 == 0
+    }
+
+    /// 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 value in-place, use [`make_ascii_uppercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let lowercase_a = 97u8;
+    ///
+    /// assert_eq!(65, lowercase_a.to_ascii_uppercase());
+    /// ```
+    ///
+    /// [`make_ascii_uppercase`]: #method.make_ascii_uppercase
+    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.21.0")]
+    #[inline]
+    pub fn to_ascii_uppercase(&self) -> u8 {
+        ASCII_UPPERCASE_MAP[*self as usize]
+    }
+
+    /// 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 value in-place, use [`make_ascii_lowercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let uppercase_a = 65u8;
+    ///
+    /// assert_eq!(97, uppercase_a.to_ascii_lowercase());
+    /// ```
+    ///
+    /// [`make_ascii_lowercase`]: #method.make_ascii_lowercase
+    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.21.0")]
+    #[inline]
+    pub fn to_ascii_lowercase(&self) -> u8 {
+        ASCII_LOWERCASE_MAP[*self as usize]
+    }
+
+    /// Checks that two values are an ASCII case-insensitive match.
+    ///
+    /// This is equivalent to `to_ascii_lowercase(a) == to_ascii_lowercase(b)`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let lowercase_a = 97u8;
+    /// let uppercase_a = 65u8;
+    ///
+    /// assert!(lowercase_a.eq_ignore_ascii_case(&uppercase_a));
+    /// ```
+    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.21.0")]
+    #[inline]
+    pub fn eq_ignore_ascii_case(&self, other: &u8) -> bool {
+        self.to_ascii_lowercase() == other.to_ascii_lowercase()
+    }
+
+    /// Converts this value to its ASCII upper case equivalent in-place.
+    ///
+    /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
+    /// but non-ASCII letters are unchanged.
+    ///
+    /// To return a new uppercased value without modifying the existing one, use
+    /// [`to_ascii_uppercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut byte = b'a';
+    ///
+    /// byte.make_ascii_uppercase();
+    ///
+    /// assert_eq!(b'A', byte);
+    /// ```
+    ///
+    /// [`to_ascii_uppercase`]: #method.to_ascii_uppercase
+    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.21.0")]
+    #[inline]
+    pub fn make_ascii_uppercase(&mut self) {
+        *self = self.to_ascii_uppercase();
+    }
+
+    /// Converts this value to its ASCII lower case equivalent in-place.
+    ///
+    /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
+    /// but non-ASCII letters are unchanged.
+    ///
+    /// To return a new lowercased value without modifying the existing one, use
+    /// [`to_ascii_lowercase`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let mut byte = b'A';
+    ///
+    /// byte.make_ascii_lowercase();
+    ///
+    /// assert_eq!(b'a', byte);
+    /// ```
+    ///
+    /// [`to_ascii_lowercase`]: #method.to_ascii_lowercase
+    #[stable(feature = "ascii_methods_on_intrinsics", since = "1.21.0")]
+    #[inline]
+    pub fn make_ascii_lowercase(&mut self) {
+        *self = self.to_ascii_lowercase();
+    }
+
+    /// Checks if the value is an ASCII alphabetic character:
+    ///
+    /// - U+0041 'A' ... U+005A 'Z', or
+    /// - U+0061 'a' ... U+007A 'z'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(uppercase_a.is_ascii_alphabetic());
+    /// assert!(uppercase_g.is_ascii_alphabetic());
+    /// assert!(a.is_ascii_alphabetic());
+    /// assert!(g.is_ascii_alphabetic());
+    /// assert!(!zero.is_ascii_alphabetic());
+    /// assert!(!percent.is_ascii_alphabetic());
+    /// assert!(!space.is_ascii_alphabetic());
+    /// assert!(!lf.is_ascii_alphabetic());
+    /// assert!(!esc.is_ascii_alphabetic());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_alphabetic(&self) -> bool {
+        if *self >= 0x80 { return false; }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            L | Lx | U | Ux => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII uppercase character:
+    /// U+0041 'A' ... U+005A 'Z'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(uppercase_a.is_ascii_uppercase());
+    /// assert!(uppercase_g.is_ascii_uppercase());
+    /// assert!(!a.is_ascii_uppercase());
+    /// assert!(!g.is_ascii_uppercase());
+    /// assert!(!zero.is_ascii_uppercase());
+    /// assert!(!percent.is_ascii_uppercase());
+    /// assert!(!space.is_ascii_uppercase());
+    /// assert!(!lf.is_ascii_uppercase());
+    /// assert!(!esc.is_ascii_uppercase());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_uppercase(&self) -> bool {
+        if *self >= 0x80 { return false }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            U | Ux => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII lowercase character:
+    /// U+0061 'a' ... U+007A 'z'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(!uppercase_a.is_ascii_lowercase());
+    /// assert!(!uppercase_g.is_ascii_lowercase());
+    /// assert!(a.is_ascii_lowercase());
+    /// assert!(g.is_ascii_lowercase());
+    /// assert!(!zero.is_ascii_lowercase());
+    /// assert!(!percent.is_ascii_lowercase());
+    /// assert!(!space.is_ascii_lowercase());
+    /// assert!(!lf.is_ascii_lowercase());
+    /// assert!(!esc.is_ascii_lowercase());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_lowercase(&self) -> bool {
+        if *self >= 0x80 { return false }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            L | Lx => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII alphanumeric character:
+    ///
+    /// - U+0041 'A' ... U+005A 'Z', or
+    /// - U+0061 'a' ... U+007A 'z', or
+    /// - U+0030 '0' ... U+0039 '9'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(uppercase_a.is_ascii_alphanumeric());
+    /// assert!(uppercase_g.is_ascii_alphanumeric());
+    /// assert!(a.is_ascii_alphanumeric());
+    /// assert!(g.is_ascii_alphanumeric());
+    /// assert!(zero.is_ascii_alphanumeric());
+    /// assert!(!percent.is_ascii_alphanumeric());
+    /// assert!(!space.is_ascii_alphanumeric());
+    /// assert!(!lf.is_ascii_alphanumeric());
+    /// assert!(!esc.is_ascii_alphanumeric());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_alphanumeric(&self) -> bool {
+        if *self >= 0x80 { return false }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            D | L | Lx | U | Ux => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII decimal digit:
+    /// U+0030 '0' ... U+0039 '9'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(!uppercase_a.is_ascii_digit());
+    /// assert!(!uppercase_g.is_ascii_digit());
+    /// assert!(!a.is_ascii_digit());
+    /// assert!(!g.is_ascii_digit());
+    /// assert!(zero.is_ascii_digit());
+    /// assert!(!percent.is_ascii_digit());
+    /// assert!(!space.is_ascii_digit());
+    /// assert!(!lf.is_ascii_digit());
+    /// assert!(!esc.is_ascii_digit());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_digit(&self) -> bool {
+        if *self >= 0x80 { return false }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            D => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII hexadecimal digit:
+    ///
+    /// - U+0030 '0' ... U+0039 '9', or
+    /// - U+0041 'A' ... U+0046 'F', or
+    /// - U+0061 'a' ... U+0066 'f'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(uppercase_a.is_ascii_hexdigit());
+    /// assert!(!uppercase_g.is_ascii_hexdigit());
+    /// assert!(a.is_ascii_hexdigit());
+    /// assert!(!g.is_ascii_hexdigit());
+    /// assert!(zero.is_ascii_hexdigit());
+    /// assert!(!percent.is_ascii_hexdigit());
+    /// assert!(!space.is_ascii_hexdigit());
+    /// assert!(!lf.is_ascii_hexdigit());
+    /// assert!(!esc.is_ascii_hexdigit());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_hexdigit(&self) -> bool {
+        if *self >= 0x80 { return false }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            D | Lx | Ux => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII punctuation character:
+    ///
+    /// - U+0021 ... U+002F `! " # $ % & ' ( ) * + , - . /`, or
+    /// - U+003A ... U+0040 `: ; < = > ? @`, or
+    /// - U+005B ... U+0060 ``[ \ ] ^ _ ` ``, or
+    /// - U+007B ... U+007E `{ | } ~`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(!uppercase_a.is_ascii_punctuation());
+    /// assert!(!uppercase_g.is_ascii_punctuation());
+    /// assert!(!a.is_ascii_punctuation());
+    /// assert!(!g.is_ascii_punctuation());
+    /// assert!(!zero.is_ascii_punctuation());
+    /// assert!(percent.is_ascii_punctuation());
+    /// assert!(!space.is_ascii_punctuation());
+    /// assert!(!lf.is_ascii_punctuation());
+    /// assert!(!esc.is_ascii_punctuation());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_punctuation(&self) -> bool {
+        if *self >= 0x80 { return false }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            P => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII graphic character:
+    /// U+0021 '@' ... U+007E '~'.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(uppercase_a.is_ascii_graphic());
+    /// assert!(uppercase_g.is_ascii_graphic());
+    /// assert!(a.is_ascii_graphic());
+    /// assert!(g.is_ascii_graphic());
+    /// assert!(zero.is_ascii_graphic());
+    /// assert!(percent.is_ascii_graphic());
+    /// assert!(!space.is_ascii_graphic());
+    /// assert!(!lf.is_ascii_graphic());
+    /// assert!(!esc.is_ascii_graphic());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_graphic(&self) -> bool {
+        if *self >= 0x80 { return false; }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            Ux | U | Lx | L | D | P => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII whitespace character:
+    /// U+0020 SPACE, U+0009 HORIZONTAL TAB, U+000A LINE FEED,
+    /// U+000C FORM FEED, or U+000D CARRIAGE RETURN.
+    ///
+    /// Rust uses the WhatWG Infra Standard's [definition of ASCII
+    /// whitespace][infra-aw]. There are several other definitions in
+    /// wide use. For instance, [the POSIX locale][pct] includes
+    /// U+000B VERTICAL TAB as well as all the above characters,
+    /// but—from the very same specification—[the default rule for
+    /// "field splitting" in the Bourne shell][bfs] considers *only*
+    /// SPACE, HORIZONTAL TAB, and LINE FEED as whitespace.
+    ///
+    /// If you are writing a program that will process an existing
+    /// file format, check what that format's definition of whitespace is
+    /// before using this function.
+    ///
+    /// [infra-aw]: https://infra.spec.whatwg.org/#ascii-whitespace
+    /// [pct]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_01
+    /// [bfs]: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(!uppercase_a.is_ascii_whitespace());
+    /// assert!(!uppercase_g.is_ascii_whitespace());
+    /// assert!(!a.is_ascii_whitespace());
+    /// assert!(!g.is_ascii_whitespace());
+    /// assert!(!zero.is_ascii_whitespace());
+    /// assert!(!percent.is_ascii_whitespace());
+    /// assert!(space.is_ascii_whitespace());
+    /// assert!(lf.is_ascii_whitespace());
+    /// assert!(!esc.is_ascii_whitespace());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_whitespace(&self) -> bool {
+        if *self >= 0x80 { return false; }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            Cw | W => true,
+            _ => false
+        }
+    }
+
+    /// Checks if the value is an ASCII control character:
+    /// U+0000 NUL ... U+001F UNIT SEPARATOR, or U+007F DELETE.
+    /// Note that most ASCII whitespace characters are control
+    /// characters, but SPACE is not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(ascii_ctype)]
+    ///
+    /// let uppercase_a = b'A';
+    /// let uppercase_g = b'G';
+    /// let a = b'a';
+    /// let g = b'g';
+    /// let zero = b'0';
+    /// let percent = b'%';
+    /// let space = b' ';
+    /// let lf = b'\n';
+    /// let esc = 0x1b_u8;
+    ///
+    /// assert!(!uppercase_a.is_ascii_control());
+    /// assert!(!uppercase_g.is_ascii_control());
+    /// assert!(!a.is_ascii_control());
+    /// assert!(!g.is_ascii_control());
+    /// assert!(!zero.is_ascii_control());
+    /// assert!(!percent.is_ascii_control());
+    /// assert!(!space.is_ascii_control());
+    /// assert!(lf.is_ascii_control());
+    /// assert!(esc.is_ascii_control());
+    /// ```
+    #[stable(feature = "ascii_ctype_on_intrinsics", since = "1.24.0")]
+    #[inline]
+    pub fn is_ascii_control(&self) -> bool {
+        if *self >= 0x80 { return false; }
+        match ASCII_CHARACTER_CLASS[*self as usize] {
+            C | Cw => true,
+            _ => false
+        }
+    }
 }
 
 #[lang = "u16"]
@@ -2507,16 +3064,24 @@ impl fmt::Display for TryFromIntError {
     }
 }
 
+#[unstable(feature = "try_from", issue = "33417")]
+impl From<Infallible> for TryFromIntError {
+    fn from(infallible: Infallible) -> TryFromIntError {
+        match infallible {
+        }
+    }
+}
+
 // no possible bounds violation
 macro_rules! try_from_unbounded {
     ($source:ty, $($target:ty),*) => {$(
         #[unstable(feature = "try_from", issue = "33417")]
         impl TryFrom<$source> for $target {
-            type Error = TryFromIntError;
+            type Error = Infallible;
 
             #[inline]
-            fn try_from(u: $source) -> Result<$target, TryFromIntError> {
-                Ok(u as $target)
+            fn try_from(value: $source) -> Result<Self, Self::Error> {
+                Ok(value as $target)
             }
         }
     )*}
@@ -2588,31 +3153,17 @@ macro_rules! rev {
 }
 
 /// intra-sign conversions
-try_from_unbounded!(u8, u8, u16, u32, u64, u128);
-try_from_unbounded!(u16, u16, u32, u64, u128);
-try_from_unbounded!(u32, u32, u64, u128);
-try_from_unbounded!(u64, u64, u128);
-try_from_unbounded!(u128, u128);
 try_from_upper_bounded!(u16, u8);
 try_from_upper_bounded!(u32, u16, u8);
 try_from_upper_bounded!(u64, u32, u16, u8);
 try_from_upper_bounded!(u128, u64, u32, u16, u8);
 
-try_from_unbounded!(i8, i8, i16, i32, i64, i128);
-try_from_unbounded!(i16, i16, i32, i64, i128);
-try_from_unbounded!(i32, i32, i64, i128);
-try_from_unbounded!(i64, i64, i128);
-try_from_unbounded!(i128, i128);
 try_from_both_bounded!(i16, i8);
 try_from_both_bounded!(i32, i16, i8);
 try_from_both_bounded!(i64, i32, i16, i8);
 try_from_both_bounded!(i128, i64, i32, i16, i8);
 
 // unsigned-to-signed
-try_from_unbounded!(u8, i16, i32, i64, i128);
-try_from_unbounded!(u16, i32, i64, i128);
-try_from_unbounded!(u32, i64, i128);
-try_from_unbounded!(u64, i128);
 try_from_upper_bounded!(u8, i8);
 try_from_upper_bounded!(u16, i8, i16);
 try_from_upper_bounded!(u32, i8, i16, i32);
@@ -2631,15 +3182,13 @@ try_from_both_bounded!(i64, u32, u16, u8);
 try_from_both_bounded!(i128, u64, u32, u16, u8);
 
 // usize/isize
-try_from_unbounded!(usize, usize);
 try_from_upper_bounded!(usize, isize);
 try_from_lower_bounded!(isize, usize);
-try_from_unbounded!(isize, isize);
 
 #[cfg(target_pointer_width = "16")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::TryFrom;
+    use convert::{Infallible, TryFrom};
 
     try_from_upper_bounded!(usize, u8);
     try_from_unbounded!(usize, u16, u32, u64, u128);
@@ -2651,21 +3200,21 @@ mod ptr_try_from_impls {
     try_from_both_bounded!(isize, i8);
     try_from_unbounded!(isize, i16, i32, i64, i128);
 
-    rev!(try_from_unbounded, usize, u8, u16);
+    rev!(try_from_unbounded, usize, u16);
     rev!(try_from_upper_bounded, usize, u32, u64, u128);
     rev!(try_from_lower_bounded, usize, i8, i16);
     rev!(try_from_both_bounded, usize, i32, i64, i128);
 
     rev!(try_from_unbounded, isize, u8);
     rev!(try_from_upper_bounded, isize, u16, u32, u64, u128);
-    rev!(try_from_unbounded, isize, i8, i16);
+    rev!(try_from_unbounded, isize, i16);
     rev!(try_from_both_bounded, isize, i32, i64, i128);
 }
 
 #[cfg(target_pointer_width = "32")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::TryFrom;
+    use convert::{Infallible, TryFrom};
 
     try_from_upper_bounded!(usize, u8, u16);
     try_from_unbounded!(usize, u32, u64, u128);
@@ -2677,21 +3226,21 @@ mod ptr_try_from_impls {
     try_from_both_bounded!(isize, i8, i16);
     try_from_unbounded!(isize, i32, i64, i128);
 
-    rev!(try_from_unbounded, usize, u8, u16, u32);
+    rev!(try_from_unbounded, usize, u16, u32);
     rev!(try_from_upper_bounded, usize, u64, u128);
     rev!(try_from_lower_bounded, usize, i8, i16, i32);
     rev!(try_from_both_bounded, usize, i64, i128);
 
     rev!(try_from_unbounded, isize, u8, u16);
     rev!(try_from_upper_bounded, isize, u32, u64, u128);
-    rev!(try_from_unbounded, isize, i8, i16, i32);
+    rev!(try_from_unbounded, isize, i16, i32);
     rev!(try_from_both_bounded, isize, i64, i128);
 }
 
 #[cfg(target_pointer_width = "64")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::TryFrom;
+    use convert::{Infallible, TryFrom};
 
     try_from_upper_bounded!(usize, u8, u16, u32);
     try_from_unbounded!(usize, u64, u128);
@@ -2703,14 +3252,14 @@ mod ptr_try_from_impls {
     try_from_both_bounded!(isize, i8, i16, i32);
     try_from_unbounded!(isize, i64, i128);
 
-    rev!(try_from_unbounded, usize, u8, u16, u32, u64);
+    rev!(try_from_unbounded, usize, u16, u32, u64);
     rev!(try_from_upper_bounded, usize, u128);
     rev!(try_from_lower_bounded, usize, i8, i16, i32, i64);
     rev!(try_from_both_bounded, usize, i128);
 
     rev!(try_from_unbounded, isize, u8, u16, u32);
     rev!(try_from_upper_bounded, isize, u64, u128);
-    rev!(try_from_unbounded, isize, i8, i16, i32, i64);
+    rev!(try_from_unbounded, isize, i16, i32, i64);
     rev!(try_from_both_bounded, isize, i128);
 }
 
@@ -2934,3 +3483,106 @@ impl_from! { u32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
 
 // Float -> Float
 impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0")] }
+
+static ASCII_LOWERCASE_MAP: [u8; 256] = [
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    b' ', b'!', b'"', b'#', b'$', b'%', b'&', b'\'',
+    b'(', b')', b'*', b'+', b',', b'-', b'.', b'/',
+    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7',
+    b'8', b'9', b':', b';', b'<', b'=', b'>', b'?',
+    b'@',
+
+          b'a', b'b', b'c', b'd', b'e', b'f', b'g',
+    b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o',
+    b'p', b'q', b'r', b's', b't', b'u', b'v', b'w',
+    b'x', b'y', b'z',
+
+                      b'[', b'\\', b']', b'^', b'_',
+    b'`', b'a', b'b', b'c', b'd', b'e', b'f', b'g',
+    b'h', b'i', b'j', b'k', b'l', b'm', b'n', b'o',
+    b'p', b'q', b'r', b's', b't', b'u', b'v', b'w',
+    b'x', b'y', b'z', b'{', b'|', b'}', b'~', 0x7f,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+];
+
+static ASCII_UPPERCASE_MAP: [u8; 256] = [
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    b' ', b'!', b'"', b'#', b'$', b'%', b'&', b'\'',
+    b'(', b')', b'*', b'+', b',', b'-', b'.', b'/',
+    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7',
+    b'8', b'9', b':', b';', b'<', b'=', b'>', b'?',
+    b'@', b'A', b'B', b'C', b'D', b'E', b'F', b'G',
+    b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O',
+    b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W',
+    b'X', b'Y', b'Z', b'[', b'\\', b']', b'^', b'_',
+    b'`',
+
+          b'A', b'B', b'C', b'D', b'E', b'F', b'G',
+    b'H', b'I', b'J', b'K', b'L', b'M', b'N', b'O',
+    b'P', b'Q', b'R', b'S', b'T', b'U', b'V', b'W',
+    b'X', b'Y', b'Z',
+
+                      b'{', b'|', b'}', b'~', 0x7f,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+];
+
+enum AsciiCharacterClass {
+    C,  // control
+    Cw, // control whitespace
+    W,  // whitespace
+    D,  // digit
+    L,  // lowercase
+    Lx, // lowercase hex digit
+    U,  // uppercase
+    Ux, // uppercase hex digit
+    P,  // punctuation
+}
+use self::AsciiCharacterClass::*;
+
+static ASCII_CHARACTER_CLASS: [AsciiCharacterClass; 128] = [
+//  _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 _a _b _c _d _e _f
+    C, C, C, C, C, C, C, C, C, Cw,Cw,C, Cw,Cw,C, C, // 0_
+    C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, // 1_
+    W, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, // 2_
+    D, D, D, D, D, D, D, D, D, D, P, P, P, P, P, P, // 3_
+    P, Ux,Ux,Ux,Ux,Ux,Ux,U, U, U, U, U, U, U, U, U, // 4_
+    U, U, U, U, U, U, U, U, U, U, U, P, P, P, P, P, // 5_
+    P, Lx,Lx,Lx,Lx,Lx,Lx,L, L, L, L, L, L, L, L, L, // 6_
+    L, L, L, L, L, L, L, L, L, L, L, P, P, P, P, C, // 7_
+];
diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index acdf685e850..ae1b0b3ce11 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -36,6 +36,7 @@ macro_rules! sh_impl_signed {
                 *self = *self << other;
             }
         }
+        forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Shr<$f> for Wrapping<$t> {
@@ -58,6 +59,7 @@ macro_rules! sh_impl_signed {
                 *self = *self >> other;
             }
         }
+        forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
     )
 }
 
@@ -80,6 +82,7 @@ macro_rules! sh_impl_unsigned {
                 *self = *self << other;
             }
         }
+        forward_ref_op_assign! { impl ShlAssign, shl_assign for Wrapping<$t>, $f }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Shr<$f> for Wrapping<$t> {
@@ -98,6 +101,7 @@ macro_rules! sh_impl_unsigned {
                 *self = *self >> other;
             }
         }
+        forward_ref_op_assign! { impl ShrAssign, shr_assign for Wrapping<$t>, $f }
     )
 }
 
@@ -142,6 +146,7 @@ macro_rules! wrapping_impl {
                 *self = *self + other;
             }
         }
+        forward_ref_op_assign! { impl AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Sub for Wrapping<$t> {
@@ -162,6 +167,7 @@ macro_rules! wrapping_impl {
                 *self = *self - other;
             }
         }
+        forward_ref_op_assign! { impl SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Mul for Wrapping<$t> {
@@ -182,6 +188,7 @@ macro_rules! wrapping_impl {
                 *self = *self * other;
             }
         }
+        forward_ref_op_assign! { impl MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "wrapping_div", since = "1.3.0")]
         impl Div for Wrapping<$t> {
@@ -202,6 +209,7 @@ macro_rules! wrapping_impl {
                 *self = *self / other;
             }
         }
+        forward_ref_op_assign! { impl DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "wrapping_impls", since = "1.7.0")]
         impl Rem for Wrapping<$t> {
@@ -222,6 +230,7 @@ macro_rules! wrapping_impl {
                 *self = *self % other;
             }
         }
+        forward_ref_op_assign! { impl RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Not for Wrapping<$t> {
@@ -254,6 +263,7 @@ macro_rules! wrapping_impl {
                 *self = *self ^ other;
             }
         }
+        forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl BitOr for Wrapping<$t> {
@@ -274,6 +284,7 @@ macro_rules! wrapping_impl {
                 *self = *self | other;
             }
         }
+        forward_ref_op_assign! { impl BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl BitAnd for Wrapping<$t> {
@@ -294,6 +305,7 @@ macro_rules! wrapping_impl {
                 *self = *self & other;
             }
         }
+        forward_ref_op_assign! { impl BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> }
 
         #[stable(feature = "wrapping_neg", since = "1.10.0")]
         impl Neg for Wrapping<$t> {
diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs
index 62007caedd3..8b3d662a6db 100644
--- a/src/libcore/ops/arith.rs
+++ b/src/libcore/ops/arith.rs
@@ -662,6 +662,8 @@ macro_rules! add_assign_impl {
             #[rustc_inherit_overflow_checks]
             fn add_assign(&mut self, other: $t) { *self += other }
         }
+
+        forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
     )+)
 }
 
@@ -713,6 +715,8 @@ macro_rules! sub_assign_impl {
             #[rustc_inherit_overflow_checks]
             fn sub_assign(&mut self, other: $t) { *self -= other }
         }
+
+        forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
     )+)
 }
 
@@ -755,6 +759,8 @@ macro_rules! mul_assign_impl {
             #[rustc_inherit_overflow_checks]
             fn mul_assign(&mut self, other: $t) { *self *= other }
         }
+
+        forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
     )+)
 }
 
@@ -796,6 +802,8 @@ macro_rules! div_assign_impl {
             #[inline]
             fn div_assign(&mut self, other: $t) { *self /= other }
         }
+
+        forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
     )+)
 }
 
@@ -841,6 +849,8 @@ macro_rules! rem_assign_impl {
             #[inline]
             fn rem_assign(&mut self, other: $t) { *self %= other }
         }
+
+        forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
     )+)
 }
 
diff --git a/src/libcore/ops/bit.rs b/src/libcore/ops/bit.rs
index 0bc5e554cb3..7ac5fc4debf 100644
--- a/src/libcore/ops/bit.rs
+++ b/src/libcore/ops/bit.rs
@@ -593,6 +593,8 @@ macro_rules! bitand_assign_impl {
             #[inline]
             fn bitand_assign(&mut self, other: $t) { *self &= other }
         }
+
+        forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t }
     )+)
 }
 
@@ -638,6 +640,8 @@ macro_rules! bitor_assign_impl {
             #[inline]
             fn bitor_assign(&mut self, other: $t) { *self |= other }
         }
+
+        forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t }
     )+)
 }
 
@@ -683,6 +687,8 @@ macro_rules! bitxor_assign_impl {
             #[inline]
             fn bitxor_assign(&mut self, other: $t) { *self ^= other }
         }
+
+        forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t }
     )+)
 }
 
@@ -729,6 +735,8 @@ macro_rules! shl_assign_impl {
                 *self <<= other
             }
         }
+
+        forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
     )
 }
 
@@ -793,6 +801,8 @@ macro_rules! shr_assign_impl {
                 *self >>= other
             }
         }
+
+        forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
     )
 }
 
diff --git a/src/libcore/ops/deref.rs b/src/libcore/ops/deref.rs
index ea8dd820878..80c48c7b28e 100644
--- a/src/libcore/ops/deref.rs
+++ b/src/libcore/ops/deref.rs
@@ -18,7 +18,7 @@
 /// Implementing `Deref` for smart pointers makes accessing the data behind them
 /// convenient, which is why they implement `Deref`. On the other hand, the
 /// rules regarding `Deref` and [`DerefMut`] were designed specifically to
-/// accomodate smart pointers. Because of this, **`Deref` should only be
+/// accommodate smart pointers. Because of this, **`Deref` should only be
 /// implemented for smart pointers** to avoid confusion.
 ///
 /// For similar reasons, **this trait should never fail**. Failure during
@@ -40,7 +40,7 @@
 /// [book]: ../../book/second-edition/ch15-02-deref.html
 /// [`DerefMut`]: trait.DerefMut.html
 /// [more]: #more-on-deref-coercion
-/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
+/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
 /// [ref-deref-trait]: ../../reference/the-deref-trait.html
 /// [type coercions]: ../../reference/type-coercions.html
 ///
@@ -103,7 +103,7 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
 /// Implementing `DerefMut` for smart pointers makes mutating the data behind
 /// them convenient, which is why they implement `DerefMut`. On the other hand,
 /// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
-/// accomodate smart pointers. Because of this, **`DerefMut` should only be
+/// accommodate smart pointers. Because of this, **`DerefMut` should only be
 /// implemented for smart pointers** to avoid confusion.
 ///
 /// For similar reasons, **this trait should never fail**. Failure during
@@ -127,7 +127,7 @@ impl<'a, T: ?Sized> Deref for &'a mut T {
 /// [book]: ../../book/second-edition/ch15-02-deref.html
 /// [`Deref`]: trait.Deref.html
 /// [more]: #more-on-deref-coercion
-/// [ref-deref-op]: ../../reference/expressions.html#the-dereference-operator
+/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
 /// [ref-deref-trait]: ../../reference/the-deref-trait.html
 /// [type coercions]: ../../reference/type-coercions.html
 ///
diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs
index 798c182bc6e..dc7669d195c 100644
--- a/src/libcore/ops/generator.rs
+++ b/src/libcore/ops/generator.rs
@@ -14,7 +14,7 @@
 /// possible return values of a generator. Currently this corresponds to either
 /// a suspension point (`Yielded`) or a termination point (`Complete`).
 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
-#[cfg_attr(not(stage0), lang = "generator_state")]
+#[lang = "generator_state"]
 #[unstable(feature = "generator_trait", issue = "43122")]
 pub enum GeneratorState<Y, R> {
     /// The generator suspended with a value.
@@ -70,7 +70,7 @@ pub enum GeneratorState<Y, R> {
 /// More documentation of generators can be found in the unstable book.
 ///
 /// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
-#[cfg_attr(not(stage0), lang = "generator")]
+#[lang = "generator"]
 #[unstable(feature = "generator_trait", issue = "43122")]
 #[fundamental]
 pub trait Generator {
diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs
index 8975b680ca7..70ef4487334 100644
--- a/src/libcore/ops/mod.rs
+++ b/src/libcore/ops/mod.rs
@@ -150,7 +150,7 @@
 //! [`Sub`]: trait.Sub.html
 //! [`Mul`]: trait.Mul.html
 //! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
-//! [operator precedence]: ../../reference/expressions.html#operator-precedence
+//! [operator precedence]: ../../reference/expressions.html#expression-precedence
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libcore/ops/try.rs b/src/libcore/ops/try.rs
index e788b66a1ec..81e5cb5c350 100644
--- a/src/libcore/ops/try.rs
+++ b/src/libcore/ops/try.rs
@@ -15,24 +15,19 @@
 /// extracting those success or failure values from an existing instance and
 /// creating a new instance from a success or failure value.
 #[unstable(feature = "try_trait", issue = "42327")]
-#[cfg_attr(stage0,
-           rustc_on_unimplemented = "the `?` operator can only be used in a \
-                                     function that returns `Result` \
-                                     (or another type that implements `{Try}`)")]
-#[cfg_attr(not(stage0),
-           rustc_on_unimplemented(
-               on(all(
-                   any(from_method="from_error", from_method="from_ok"),
-                   from_desugaring="?"),
-                  message="the `?` operator can only be used in a \
-                           function that returns `Result` \
-                           (or another type that implements `{Try}`)",
-                  label="cannot use the `?` operator in a function that returns `{Self}`"),
-               on(all(from_method="into_result", from_desugaring="?"),
-                  message="the `?` operator can only be applied to values \
-                           that implement `{Try}`",
-                  label="the `?` operator cannot be applied to type `{Self}`")
-))]
+#[rustc_on_unimplemented(
+   on(all(
+       any(from_method="from_error", from_method="from_ok"),
+       from_desugaring="?"),
+      message="the `?` operator can only be used in a \
+               function that returns `Result` \
+               (or another type that implements `{Try}`)",
+      label="cannot use the `?` operator in a function that returns `{Self}`"),
+   on(all(from_method="into_result", from_desugaring="?"),
+      message="the `?` operator can only be applied to values \
+               that implement `{Try}`",
+      label="the `?` operator cannot be applied to type `{Self}`")
+)]
 pub trait Try {
     /// The type of this value when viewed as successful.
     #[unstable(feature = "try_trait", issue = "42327")]
diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs
index 58da290cfb6..cd896859b16 100644
--- a/src/libcore/ops/unsize.rs
+++ b/src/libcore/ops/unsize.rs
@@ -42,7 +42,7 @@ use marker::Unsize;
 /// [unsize]: ../marker/trait.Unsize.html
 /// [nomicon-coerce]: ../../nomicon/coercions.html
 #[unstable(feature = "coerce_unsized", issue = "27732")]
-#[lang="coerce_unsized"]
+#[lang = "coerce_unsized"]
 pub trait CoerceUnsized<T> {
     // Empty.
 }
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 138e04c7737..12e6e843056 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -146,7 +146,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use iter::{FromIterator, FusedIterator, TrustedLen};
-use mem;
+use {mem, ops};
 
 // Note that this is not a lang item per se, but it has a hidden dependency on
 // `Iterator`, which is one. The compiler assumes that the `next` method of
@@ -607,6 +607,41 @@ impl<T> Option<T> {
         }
     }
 
+    /// Returns `None` if the option is `None`, otherwise calls `predicate`
+    /// with the wrapped value and returns:
+    ///
+    /// - `Some(t)` if `predicate` returns `true` (where `t` is the wrapped
+    ///   value), and
+    /// - `None` if `predicate` returns `false`.
+    ///
+    /// This function works similar to `Iterator::filter()`. You can imagine
+    /// the `Option<T>` being an iterator over one or zero elements. `filter()`
+    /// lets you decide which elements to keep.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// #![feature(option_filter)]
+    ///
+    /// fn is_even(n: &i32) -> bool {
+    ///     n % 2 == 0
+    /// }
+    ///
+    /// assert_eq!(None.filter(is_even), None);
+    /// assert_eq!(Some(3).filter(is_even), None);
+    /// assert_eq!(Some(4).filter(is_even), Some(4));
+    /// ```
+    #[inline]
+    #[unstable(feature = "option_filter", issue = "45860")]
+    pub fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Self {
+        if let Some(x) = self {
+            if predicate(&x) {
+                return Some(x)
+            }
+        }
+        None
+    }
+
     /// Returns the option if it contains a value, otherwise returns `optb`.
     ///
     /// # Examples
@@ -1123,3 +1158,29 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
         }
     }
 }
+
+/// The error type that results from applying the try operator (`?`) to a `None` value. If you wish
+/// to allow `x?` (where `x` is an `Option<T>`) to be converted into your error type, you can
+/// implement `impl From<NoneError>` for `YourErrorType`. In that case, `x?` within a function that
+/// returns `Result<_, YourErrorType>` will translate a `None` value into an `Err` result.
+#[unstable(feature = "try_trait", issue = "42327")]
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+pub struct NoneError;
+
+#[unstable(feature = "try_trait", issue = "42327")]
+impl<T> ops::Try for Option<T> {
+    type Ok = T;
+    type Error = NoneError;
+
+    fn into_result(self) -> Result<T, NoneError> {
+        self.ok_or(NoneError)
+    }
+
+    fn from_ok(v: T) -> Self {
+        Some(v)
+    }
+
+    fn from_error(_: NoneError) -> Self {
+        None
+    }
+}
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 4041a3760e5..5e70c8283f4 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -27,8 +27,6 @@ use nonzero::NonZero;
 
 use cmp::Ordering::{self, Less, Equal, Greater};
 
-// FIXME #19649: intrinsic docs don't render, so these have no docs :(
-
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use intrinsics::copy_nonoverlapping;
 
@@ -56,7 +54,7 @@ pub use intrinsics::write_bytes;
 /// This has all the same safety problems as `ptr::read` with respect to
 /// invalid pointers, types, and double drops.
 #[stable(feature = "drop_in_place", since = "1.8.0")]
-#[lang="drop_in_place"]
+#[lang = "drop_in_place"]
 #[allow(unconditional_recursion)]
 pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     // Code here does not matter - this is replaced by the
@@ -76,7 +74,6 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_ptr_null"))]
 pub const fn null<T>() -> *const T { 0 as *const T }
 
 /// Creates a null mutable raw pointer.
@@ -91,7 +88,6 @@ pub const fn null<T>() -> *const T { 0 as *const T }
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_ptr_null_mut"))]
 pub const fn null_mut<T>() -> *mut T { 0 as *mut T }
 
 /// Swaps the values at two mutable locations of the same type, without
@@ -230,7 +226,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
 /// moves the value out of `src` without preventing further usage of `src`.
 /// If `T` is not `Copy`, then care must be taken to ensure that the value at
 /// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
+/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
 /// because it will attempt to drop the value previously at `*src`.
 ///
 /// The pointer must be aligned; use `read_unaligned` if that is not the case.
@@ -266,7 +262,7 @@ pub unsafe fn read<T>(src: *const T) -> T {
 /// moves the value out of `src` without preventing further usage of `src`.
 /// If `T` is not `Copy`, then care must be taken to ensure that the value at
 /// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
+/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
 /// because it will attempt to drop the value previously at `*src`.
 ///
 /// # Examples
@@ -399,7 +395,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
 /// moves the value out of `src` without preventing further usage of `src`.
 /// If `T` is not `Copy`, then care must be taken to ensure that the value at
 /// `src` is not used before the data is overwritten again (e.g. with `write`,
-/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use
+/// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use
 /// because it will attempt to drop the value previously at `*src`.
 ///
 /// # Examples
@@ -476,6 +472,11 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
 impl<T: ?Sized> *const T {
     /// Returns `true` if the pointer is null.
     ///
+    /// Note that unsized types have many possible null pointers, as only the
+    /// raw data pointer is considered, not their length, vtable, etc.
+    /// Therefore, two pointers that are null may still not compare equal to
+    /// each other.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -487,8 +488,10 @@ impl<T: ?Sized> *const T {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn is_null(self) -> bool where T: Sized {
-        self == null()
+    pub fn is_null(self) -> bool {
+        // Compare via a cast to a thin pointer, so fat pointers are only
+        // considering their "data" part for null-ness.
+        (self as *const u8) == null()
     }
 
     /// Returns `None` if the pointer is null, or else returns a reference to
@@ -519,7 +522,7 @@ impl<T: ?Sized> *const T {
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[inline]
-    pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
+    pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
         if self.is_null() {
             None
         } else {
@@ -553,7 +556,7 @@ impl<T: ?Sized> *const T {
     ///
     /// Most platforms fundamentally can't even construct such an allocation.
     /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2^63 bytes due to page-table limitations or splitting the address space.
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
     /// more than `isize::MAX` bytes with things like Physical Address
     /// Extension. As such, memory acquired directly from allocators or memory
@@ -686,7 +689,7 @@ impl<T: ?Sized> *const T {
     ///
     /// Most platforms fundamentally can't even construct such an allocation.
     /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2^63 bytes due to page-table limitations or splitting the address space.
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
     /// more than `isize::MAX` bytes with things like Physical Address
     /// Extension. As such, memory acquired directly from allocators or memory
@@ -745,7 +748,7 @@ impl<T: ?Sized> *const T {
     ///
     /// Most platforms fundamentally can't even construct such an allocation.
     /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2^63 bytes due to page-table limitations or splitting the address space.
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
     /// more than `isize::MAX` bytes with things like Physical Address
     /// Extension. As such, memory acquired directly from allocators or memory
@@ -873,7 +876,7 @@ impl<T: ?Sized> *const T {
     /// moves the value out of `self` without preventing further usage of `self`.
     /// If `T` is not `Copy`, then care must be taken to ensure that the value at
     /// `self` is not used before the data is overwritten again (e.g. with `write`,
-    /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use
+    /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
     /// because it will attempt to drop the value previously at `*self`.
     ///
     /// The pointer must be aligned; use `read_unaligned` if that is not the case.
@@ -927,7 +930,7 @@ impl<T: ?Sized> *const T {
     /// moves the value out of `self` without preventing further usage of `self`.
     /// If `T` is not `Copy`, then care must be taken to ensure that the value at
     /// `self` is not used before the data is overwritten again (e.g. with `write`,
-    /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use
+    /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
     /// because it will attempt to drop the value previously at `*self`.
     ///
     /// # Examples
@@ -963,7 +966,7 @@ impl<T: ?Sized> *const T {
     /// moves the value out of `self` without preventing further usage of `self`.
     /// If `T` is not `Copy`, then care must be taken to ensure that the value at
     /// `self` is not used before the data is overwritten again (e.g. with `write`,
-    /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use
+    /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
     /// because it will attempt to drop the value previously at `*self`.
     ///
     /// # Examples
@@ -1107,6 +1110,11 @@ impl<T: ?Sized> *const T {
 impl<T: ?Sized> *mut T {
     /// Returns `true` if the pointer is null.
     ///
+    /// Note that unsized types have many possible null pointers, as only the
+    /// raw data pointer is considered, not their length, vtable, etc.
+    /// Therefore, two pointers that are null may still not compare equal to
+    /// each other.
+    ///
     /// # Examples
     ///
     /// Basic usage:
@@ -1118,8 +1126,10 @@ impl<T: ?Sized> *mut T {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn is_null(self) -> bool where T: Sized {
-        self == null_mut()
+    pub fn is_null(self) -> bool {
+        // Compare via a cast to a thin pointer, so fat pointers are only
+        // considering their "data" part for null-ness.
+        (self as *mut u8) == null_mut()
     }
 
     /// Returns `None` if the pointer is null, or else returns a reference to
@@ -1150,7 +1160,7 @@ impl<T: ?Sized> *mut T {
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[inline]
-    pub unsafe fn as_ref<'a>(self) -> Option<&'a T> where T: Sized {
+    pub unsafe fn as_ref<'a>(self) -> Option<&'a T> {
         if self.is_null() {
             None
         } else {
@@ -1184,7 +1194,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// Most platforms fundamentally can't even construct such an allocation.
     /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2^63 bytes due to page-table limitations or splitting the address space.
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
     /// more than `isize::MAX` bytes with things like Physical Address
     /// Extension. As such, memory acquired directly from allocators or memory
@@ -1274,7 +1284,7 @@ impl<T: ?Sized> *mut T {
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
     #[inline]
-    pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> where T: Sized {
+    pub unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
         if self.is_null() {
             None
         } else {
@@ -1384,7 +1394,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// Most platforms fundamentally can't even construct such an allocation.
     /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2^63 bytes due to page-table limitations or splitting the address space.
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
     /// more than `isize::MAX` bytes with things like Physical Address
     /// Extension. As such, memory acquired directly from allocators or memory
@@ -1443,7 +1453,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// Most platforms fundamentally can't even construct such an allocation.
     /// For instance, no known 64-bit platform can ever serve a request
-    /// for 2^63 bytes due to page-table limitations or splitting the address space.
+    /// for 2<sup>63</sup> bytes due to page-table limitations or splitting the address space.
     /// However, some 32-bit and 16-bit platforms may successfully serve a request for
     /// more than `isize::MAX` bytes with things like Physical Address
     /// Extension. As such, memory acquired directly from allocators or memory
@@ -1571,7 +1581,7 @@ impl<T: ?Sized> *mut T {
     /// moves the value out of `self` without preventing further usage of `self`.
     /// If `T` is not `Copy`, then care must be taken to ensure that the value at
     /// `self` is not used before the data is overwritten again (e.g. with `write`,
-    /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use
+    /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
     /// because it will attempt to drop the value previously at `*self`.
     ///
     /// The pointer must be aligned; use `read_unaligned` if that is not the case.
@@ -1625,7 +1635,7 @@ impl<T: ?Sized> *mut T {
     /// moves the value out of `self` without preventing further usage of `self`.
     /// If `T` is not `Copy`, then care must be taken to ensure that the value at
     /// `src` is not used before the data is overwritten again (e.g. with `write`,
-    /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use
+    /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
     /// because it will attempt to drop the value previously at `*self`.
     ///
     /// # Examples
@@ -1661,7 +1671,7 @@ impl<T: ?Sized> *mut T {
     /// moves the value out of `self` without preventing further usage of `self`.
     /// If `T` is not `Copy`, then care must be taken to ensure that the value at
     /// `self` is not used before the data is overwritten again (e.g. with `write`,
-    /// `zero_memory`, or `copy_memory`). Note that `*self = foo` counts as a use
+    /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use
     /// because it will attempt to drop the value previously at `*self`.
     ///
     /// # Examples
@@ -2335,7 +2345,6 @@ impl<T: ?Sized> Unique<T> {
     ///
     /// `ptr` must be non-null.
     #[unstable(feature = "unique", issue = "27730")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_unique_new"))]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
         Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
     }
@@ -2470,7 +2479,6 @@ impl<T: ?Sized> Shared<T> {
     ///
     /// `ptr` must be non-null.
     #[unstable(feature = "shared", issue = "27730")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_shared_new"))]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
         Shared { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
     }
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index ea064ca5c39..db5bffced10 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -1060,7 +1060,7 @@ unsafe impl<'a, A> TrustedLen for IterMut<'a, A> {}
 /// [`Result`]: enum.Result.html
 /// [`into_iter`]: ../iter/trait.IntoIterator.html#tymethod.into_iter
 /// [`IntoIterator`]: ../iter/trait.IntoIterator.html
-#[derive(Debug)]
+#[derive(Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IntoIter<T> { inner: Option<T> }
 
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index ae243f3f246..49c51f4f04f 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -16,9 +16,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-// FIXME: after next stage0, change RangeInclusive { ... } back to ..=
-use ops::RangeInclusive;
-
 // How this module is organized.
 //
 // The library infrastructure for slices is fairly messy. There's
@@ -43,7 +40,7 @@ use cmp;
 use fmt;
 use intrinsics::assume;
 use iter::*;
-use ops::{FnMut, self};
+use ops::{FnMut, Try, self};
 use option::Option;
 use option::Option::{None, Some};
 use result::Result;
@@ -394,23 +391,25 @@ impl<T> SliceExt for [T] {
     fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
         where F: FnMut(&'a T) -> Ordering
     {
+        let s = self;
+        let mut size = s.len();
+        if size == 0 {
+            return Err(0);
+        }
         let mut base = 0usize;
-        let mut s = self;
-
-        loop {
-            let (head, tail) = s.split_at(s.len() >> 1);
-            if tail.is_empty() {
-                return Err(base)
-            }
-            match f(&tail[0]) {
-                Less => {
-                    base += head.len() + 1;
-                    s = &tail[1..];
-                }
-                Greater => s = head,
-                Equal => return Ok(base + head.len()),
-            }
+        while size > 1 {
+            let half = size / 2;
+            let mid = base + half;
+            // mid is always in [0, size).
+            // mid >= 0: by definition
+            // mid < size: mid = size / 2 + size / 4 + size / 8 ...
+            let cmp = f(unsafe { s.get_unchecked(mid) });
+            base = if cmp == Greater { base } else { mid };
+            size -= half;
         }
+        // base is always in [0, size) because base <= mid.
+        let cmp = f(unsafe { s.get_unchecked(base) });
+        if cmp == Equal { Ok(base) } else { Err(base + (cmp == Less) as usize) }
     }
 
     #[inline]
@@ -1047,32 +1046,32 @@ impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
 
     #[inline]
     fn get(self, slice: &[T]) -> Option<&[T]> {
-        (RangeInclusive { start: 0, end: self.end }).get(slice)
+        (0..=self.end).get(slice)
     }
 
     #[inline]
     fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
-        (RangeInclusive { start: 0, end: self.end }).get_mut(slice)
+        (0..=self.end).get_mut(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked(self, slice: &[T]) -> &[T] {
-        (RangeInclusive { start: 0, end: self.end }).get_unchecked(slice)
+        (0..=self.end).get_unchecked(slice)
     }
 
     #[inline]
     unsafe fn get_unchecked_mut(self, slice: &mut [T]) -> &mut [T] {
-        (RangeInclusive { start: 0, end: self.end }).get_unchecked_mut(slice)
+        (0..=self.end).get_unchecked_mut(slice)
     }
 
     #[inline]
     fn index(self, slice: &[T]) -> &[T] {
-        (RangeInclusive { start: 0, end: self.end }).index(slice)
+        (0..=self.end).index(slice)
     }
 
     #[inline]
     fn index_mut(self, slice: &mut [T]) -> &mut [T] {
-        (RangeInclusive { start: 0, end: self.end }).index_mut(slice)
+        (0..=self.end).index_mut(slice)
     }
 }
 
@@ -1166,62 +1165,37 @@ macro_rules! iterator {
                 self.next_back()
             }
 
-            fn all<F>(&mut self, mut predicate: F) -> bool
-                where F: FnMut(Self::Item) -> bool,
-            {
-                self.search_while(true, move |elt| {
-                    if predicate(elt) {
-                        SearchWhile::Continue
-                    } else {
-                        SearchWhile::Done(false)
-                    }
-                })
-            }
-
-            fn any<F>(&mut self, mut predicate: F) -> bool
-                where F: FnMut(Self::Item) -> bool,
-            {
-                !self.all(move |elt| !predicate(elt))
-            }
-
-            fn find<F>(&mut self, mut predicate: F) -> Option<Self::Item>
-                where F: FnMut(&Self::Item) -> bool,
+            #[inline]
+            fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+                Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
             {
-                self.search_while(None, move |elt| {
-                    if predicate(&elt) {
-                        SearchWhile::Done(Some(elt))
-                    } else {
-                        SearchWhile::Continue
+                // manual unrolling is needed when there are conditional exits from the loop
+                let mut accum = init;
+                unsafe {
+                    while ptrdistance(self.ptr, self.end) >= 4 {
+                        accum = f(accum, $mkref!(self.ptr.post_inc()))?;
+                        accum = f(accum, $mkref!(self.ptr.post_inc()))?;
+                        accum = f(accum, $mkref!(self.ptr.post_inc()))?;
+                        accum = f(accum, $mkref!(self.ptr.post_inc()))?;
                     }
-                })
-            }
-
-            fn position<F>(&mut self, mut predicate: F) -> Option<usize>
-                where F: FnMut(Self::Item) -> bool,
-            {
-                let mut index = 0;
-                self.search_while(None, move |elt| {
-                    if predicate(elt) {
-                        SearchWhile::Done(Some(index))
-                    } else {
-                        index += 1;
-                        SearchWhile::Continue
+                    while self.ptr != self.end {
+                        accum = f(accum, $mkref!(self.ptr.post_inc()))?;
                     }
-                })
+                }
+                Try::from_ok(accum)
             }
 
-            fn rposition<F>(&mut self, mut predicate: F) -> Option<usize>
-                where F: FnMut(Self::Item) -> bool,
+            #[inline]
+            fn fold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
+                where Fold: FnMut(Acc, Self::Item) -> Acc,
             {
-                let mut index = self.len();
-                self.rsearch_while(None, move |elt| {
-                    index -= 1;
-                    if predicate(elt) {
-                        SearchWhile::Done(Some(index))
-                    } else {
-                        SearchWhile::Continue
-                    }
-                })
+                // Let LLVM unroll this, rather than using the default
+                // impl that would force the manual unrolling above
+                let mut accum = init;
+                while let Some(x) = self.next() {
+                    accum = f(accum, x);
+                }
+                accum
             }
         }
 
@@ -1243,59 +1217,37 @@ macro_rules! iterator {
                 }
             }
 
-            fn rfind<F>(&mut self, mut predicate: F) -> Option<Self::Item>
-                where F: FnMut(&Self::Item) -> bool,
-            {
-                self.rsearch_while(None, move |elt| {
-                    if predicate(&elt) {
-                        SearchWhile::Done(Some(elt))
-                    } else {
-                        SearchWhile::Continue
-                    }
-                })
-            }
-
-        }
-
-        // search_while is a generalization of the internal iteration methods.
-        impl<'a, T> $name<'a, T> {
-            // search through the iterator's element using the closure `g`.
-            // if no element was found, return `default`.
-            fn search_while<Acc, G>(&mut self, default: Acc, mut g: G) -> Acc
-                where Self: Sized,
-                      G: FnMut($elem) -> SearchWhile<Acc>
+            #[inline]
+            fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
+                Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
             {
                 // manual unrolling is needed when there are conditional exits from the loop
+                let mut accum = init;
                 unsafe {
                     while ptrdistance(self.ptr, self.end) >= 4 {
-                        search_while!(g($mkref!(self.ptr.post_inc())));
-                        search_while!(g($mkref!(self.ptr.post_inc())));
-                        search_while!(g($mkref!(self.ptr.post_inc())));
-                        search_while!(g($mkref!(self.ptr.post_inc())));
+                        accum = f(accum, $mkref!(self.end.pre_dec()))?;
+                        accum = f(accum, $mkref!(self.end.pre_dec()))?;
+                        accum = f(accum, $mkref!(self.end.pre_dec()))?;
+                        accum = f(accum, $mkref!(self.end.pre_dec()))?;
                     }
                     while self.ptr != self.end {
-                        search_while!(g($mkref!(self.ptr.post_inc())));
+                        accum = f(accum, $mkref!(self.end.pre_dec()))?;
                     }
                 }
-                default
+                Try::from_ok(accum)
             }
 
-            fn rsearch_while<Acc, G>(&mut self, default: Acc, mut g: G) -> Acc
-                where Self: Sized,
-                      G: FnMut($elem) -> SearchWhile<Acc>
+            #[inline]
+            fn rfold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
+                where Fold: FnMut(Acc, Self::Item) -> Acc,
             {
-                unsafe {
-                    while ptrdistance(self.ptr, self.end) >= 4 {
-                        search_while!(g($mkref!(self.end.pre_dec())));
-                        search_while!(g($mkref!(self.end.pre_dec())));
-                        search_while!(g($mkref!(self.end.pre_dec())));
-                        search_while!(g($mkref!(self.end.pre_dec())));
-                    }
-                    while self.ptr != self.end {
-                        search_while!(g($mkref!(self.end.pre_dec())));
-                    }
+                // Let LLVM unroll this, rather than using the default
+                // impl that would force the manual unrolling above
+                let mut accum = init;
+                while let Some(x) = self.next_back() {
+                    accum = f(accum, x);
                 }
-                default
+                accum
             }
         }
     }
@@ -1329,24 +1281,6 @@ macro_rules! make_mut_slice {
     }}
 }
 
-// An enum used for controlling the execution of `.search_while()`.
-enum SearchWhile<T> {
-    // Continue searching
-    Continue,
-    // Fold is complete and will return this value
-    Done(T),
-}
-
-// helper macro for search while's control flow
-macro_rules! search_while {
-    ($e:expr) => {
-        match $e {
-            SearchWhile::Continue => { }
-            SearchWhile::Done(done) => return done,
-        }
-    }
-}
-
 /// Immutable slice iterator
 ///
 /// This struct is created by the [`iter`] method on [slices].
@@ -1654,7 +1588,7 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for Split<'a, T, P> where P: FnMut(&T
     }
 }
 
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T, P> Clone for Split<'a, T, P> where P: Clone + FnMut(&T) -> bool {
     fn clone(&self) -> Split<'a, T, P> {
@@ -2093,7 +2027,7 @@ pub struct Windows<'a, T:'a> {
     size: usize
 }
 
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Windows<'a, T> {
     fn clone(&self) -> Windows<'a, T> {
@@ -2195,7 +2129,7 @@ pub struct Chunks<'a, T:'a> {
     size: usize
 }
 
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Chunks<'a, T> {
     fn clone(&self) -> Chunks<'a, T> {
@@ -2450,6 +2384,22 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
     mem::transmute(Repr { data: p, len: len })
 }
 
+/// Converts a reference to T into a slice of length 1 (without copying).
+#[unstable(feature = "from_ref", issue = "45703")]
+pub fn from_ref<T>(s: &T) -> &[T] {
+    unsafe {
+        from_raw_parts(s, 1)
+    }
+}
+
+/// Converts a reference to T into a slice of length 1 (without copying).
+#[unstable(feature = "from_ref", issue = "45703")]
+pub fn from_ref_mut<T>(s: &mut T) -> &mut [T] {
+    unsafe {
+        from_raw_parts_mut(s, 1)
+    }
+}
+
 // This function is public only because there is no other way to unit test heapsort.
 #[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "0")]
 #[doc(hidden)]
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 62367b051fc..be5108238fc 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -18,7 +18,6 @@ use self::pattern::Pattern;
 use self::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
 
 use char;
-use convert::TryFrom;
 use fmt;
 use iter::{Map, Cloned, FusedIterator, TrustedLen};
 use iter_private::TrustedRandomAccess;
@@ -77,9 +76,12 @@ pub trait FromStr: Sized {
 
     /// Parses a string `s` to return a value of this type.
     ///
-    /// If parsing succeeds, return the value inside `Ok`, otherwise
+    /// If parsing succeeds, return the value inside [`Ok`], otherwise
     /// when the string is ill-formatted return an error specific to the
-    /// inside `Err`. The error type is specific to implementation of the trait.
+    /// inside [`Err`]. The error type is specific to implementation of the trait.
+    ///
+    /// [`Ok`]: ../../std/result/enum.Result.html#variant.Ok
+    /// [`Err`]: ../../std/result/enum.Result.html#variant.Err
     ///
     /// # Examples
     ///
@@ -1407,16 +1409,6 @@ impl<'a> DoubleEndedIterator for LinesAny<'a> {
 impl<'a> FusedIterator for LinesAny<'a> {}
 
 /*
-Section: Comparing strings
-*/
-
-/// Bytewise slice equality
-#[inline]
-fn eq_slice(a: &str, b: &str) -> bool {
-    a.as_bytes() == b.as_bytes()
-}
-
-/*
 Section: UTF-8 validation
 */
 
@@ -1591,7 +1583,6 @@ mod traits {
     use cmp::Ordering;
     use ops;
     use slice::{self, SliceIndex};
-    use str::eq_slice;
 
     /// Implements ordering of strings.
     ///
@@ -1612,7 +1603,7 @@ mod traits {
     impl PartialEq for str {
         #[inline]
         fn eq(&self, other: &str) -> bool {
-            eq_slice(self, other)
+            self.as_bytes() == other.as_bytes()
         }
         #[inline]
         fn ne(&self, other: &str) -> bool { !(*self).eq(other) }
@@ -2198,7 +2189,7 @@ pub trait StrExt {
     #[stable(feature = "core", since = "1.6.0")]
     fn is_empty(&self) -> bool;
     #[stable(feature = "core", since = "1.6.0")]
-    fn parse<'a, T: TryFrom<&'a str>>(&'a self) -> Result<T, T::Error>;
+    fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
 }
 
 // truncate `&str` to length at most equal to `max`
@@ -2518,9 +2509,7 @@ impl StrExt for str {
     fn is_empty(&self) -> bool { self.len() == 0 }
 
     #[inline]
-    fn parse<'a, T>(&'a self) -> Result<T, T::Error> where T: TryFrom<&'a str> {
-        T::try_from(self)
-    }
+    fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 3dd08e69710..4c6ff4d1bb4 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -103,9 +103,8 @@ use fmt;
 ///
 /// On some platforms this function may not do anything at all.
 #[inline]
-#[unstable(feature = "hint_core_should_pause", issue = "41196")]
-pub fn hint_core_should_pause()
-{
+#[stable(feature = "spin_loop_hint", since = "1.24.0")]
+pub fn spin_loop_hint() {
     #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
     unsafe {
         asm!("pause" ::: "memory" : "volatile");
@@ -119,7 +118,9 @@ pub fn hint_core_should_pause()
 
 /// A boolean type which can be safely shared between threads.
 ///
-/// This type has the same in-memory representation as a `bool`.
+/// This type has the same in-memory representation as a [`bool`].
+///
+/// [`bool`]: ../../../std/primitive.bool.html
 #[cfg(target_has_atomic = "8")]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct AtomicBool {
@@ -241,16 +242,17 @@ impl AtomicBool {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_atomic_bool_new"))]
     pub const fn new(v: bool) -> AtomicBool {
         AtomicBool { v: UnsafeCell::new(v as u8) }
     }
 
-    /// Returns a mutable reference to the underlying `bool`.
+    /// Returns a mutable reference to the underlying [`bool`].
     ///
     /// This is safe because the mutable reference guarantees that no other threads are
     /// concurrently accessing the atomic data.
     ///
+    /// [`bool`]: ../../../std/primitive.bool.html
+    ///
     /// # Examples
     ///
     /// ```
@@ -369,7 +371,7 @@ impl AtomicBool {
         unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 }
     }
 
-    /// Stores a value into the `bool` if the current value is the same as the `current` value.
+    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
     ///
     /// The return value is always the previous value. If it is equal to `current`, then the value
     /// was updated.
@@ -378,6 +380,7 @@ impl AtomicBool {
     /// ordering of this operation.
     ///
     /// [`Ordering`]: enum.Ordering.html
+    /// [`bool`]: ../../../std/primitive.bool.html
     ///
     /// # Examples
     ///
@@ -401,7 +404,7 @@ impl AtomicBool {
         }
     }
 
-    /// Stores a value into the `bool` if the current value is the same as the `current` value.
+    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
     ///
     /// The return value is a result indicating whether the new value was written and containing
     /// the previous value. On success this value is guaranteed to be equal to `current`.
@@ -412,6 +415,7 @@ impl AtomicBool {
     /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and must
     /// be equivalent or weaker than the success ordering.
     ///
+    /// [`bool`]: ../../../std/primitive.bool.html
     /// [`Ordering`]: enum.Ordering.html
     /// [`Release`]: enum.Ordering.html#variant.Release
     /// [`AcqRel`]: enum.Ordering.html#variant.Release
@@ -452,7 +456,7 @@ impl AtomicBool {
         }
     }
 
-    /// Stores a value into the `bool` if the current value is the same as the `current` value.
+    /// Stores a value into the [`bool`] if the current value is the same as the `current` value.
     ///
     /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the
     /// comparison succeeds, which can result in more efficient code on some platforms. The
@@ -465,6 +469,7 @@ impl AtomicBool {
     /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or
     /// weaker than the success ordering.
     ///
+    /// [`bool`]: ../../../std/primitive.bool.html
     /// [`compare_exchange`]: #method.compare_exchange
     /// [`Ordering`]: enum.Ordering.html
     /// [`Release`]: enum.Ordering.html#variant.Release
@@ -650,7 +655,6 @@ impl<T> AtomicPtr<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[cfg_attr(not(stage0), rustc_const_unstable(feature = "const_atomic_ptr_new"))]
     pub const fn new(p: *mut T) -> AtomicPtr<T> {
         AtomicPtr { p: UnsafeCell::new(p) }
     }
@@ -920,16 +924,44 @@ impl<T> AtomicPtr<T> {
     }
 }
 
+#[cfg(target_has_atomic = "8")]
+#[stable(feature = "atomic_bool_from", since = "1.24.0")]
+impl From<bool> for AtomicBool {
+    #[inline]
+    fn from(b: bool) -> Self { Self::new(b) }
+}
+
+#[cfg(target_has_atomic = "ptr")]
+#[stable(feature = "atomic_from", since = "1.23.0")]
+impl<T> From<*mut T> for AtomicPtr<T> {
+    #[inline]
+    fn from(p: *mut T) -> Self { Self::new(p) }
+}
+
 #[cfg(target_has_atomic = "ptr")]
 macro_rules! atomic_int {
-    ($stable:meta, $const_unstable:meta,
+    ($stable:meta,
      $stable_cxchg:meta,
      $stable_debug:meta,
      $stable_access:meta,
+     $s_int_type:expr, $int_ref:expr,
      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
         /// An integer type which can be safely shared between threads.
         ///
-        /// This type has the same in-memory representation as the underlying integer type.
+        /// This type has the same in-memory representation as the underlying
+        /// integer type, [`
+        #[doc = $s_int_type]
+        /// `](
+        #[doc = $int_ref]
+        /// ). For more about the differences between atomic types and
+        /// non-atomic types, please see the [module-level documentation].
+        ///
+        /// Please note that examples are shared between atomic variants of
+        /// primitive integer types, so it's normal that they are all
+        /// demonstrating [`AtomicIsize`].
+        ///
+        /// [module-level documentation]: index.html
+        /// [`AtomicIsize`]: struct.AtomicIsize.html
         #[$stable]
         pub struct $atomic_type {
             v: UnsafeCell<$int_type>,
@@ -946,6 +978,12 @@ macro_rules! atomic_int {
             }
         }
 
+        #[stable(feature = "atomic_from", since = "1.23.0")]
+        impl From<$int_type> for $atomic_type {
+            #[inline]
+            fn from(v: $int_type) -> Self { Self::new(v) }
+        }
+
         #[$stable_debug]
         impl fmt::Debug for $atomic_type {
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -971,7 +1009,6 @@ macro_rules! atomic_int {
             /// ```
             #[inline]
             #[$stable]
-            #[cfg_attr(not(stage0), $const_unstable)]
             pub const fn new(v: $int_type) -> Self {
                 $atomic_type {v: UnsafeCell::new(v)}
             }
@@ -1335,91 +1372,91 @@ macro_rules! atomic_int {
 #[cfg(target_has_atomic = "8")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_i8_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "i8", "../../../std/primitive.i8.html",
     i8 AtomicI8 ATOMIC_I8_INIT
 }
 #[cfg(target_has_atomic = "8")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_u8_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "u8", "../../../std/primitive.u8.html",
     u8 AtomicU8 ATOMIC_U8_INIT
 }
 #[cfg(target_has_atomic = "16")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_i16_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "i16", "../../../std/primitive.i16.html",
     i16 AtomicI16 ATOMIC_I16_INIT
 }
 #[cfg(target_has_atomic = "16")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_u16_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "u16", "../../../std/primitive.u16.html",
     u16 AtomicU16 ATOMIC_U16_INIT
 }
 #[cfg(target_has_atomic = "32")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_i32_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "i32", "../../../std/primitive.i32.html",
     i32 AtomicI32 ATOMIC_I32_INIT
 }
 #[cfg(target_has_atomic = "32")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_u32_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "u32", "../../../std/primitive.u32.html",
     u32 AtomicU32 ATOMIC_U32_INIT
 }
 #[cfg(target_has_atomic = "64")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_i64_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "i64", "../../../std/primitive.i64.html",
     i64 AtomicI64 ATOMIC_I64_INIT
 }
 #[cfg(target_has_atomic = "64")]
 atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
-    rustc_const_unstable(feature = "const_atomic_u64_new"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "integer_atomics", issue = "32976"),
+    "u64", "../../../std/primitive.u64.html",
     u64 AtomicU64 ATOMIC_U64_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
 atomic_int!{
     stable(feature = "rust1", since = "1.0.0"),
-    rustc_const_unstable(feature = "const_atomic_isize_new"),
     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
     stable(feature = "atomic_debug", since = "1.3.0"),
     stable(feature = "atomic_access", since = "1.15.0"),
+    "isize", "../../../std/primitive.isize.html",
     isize AtomicIsize ATOMIC_ISIZE_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
 atomic_int!{
     stable(feature = "rust1", since = "1.0.0"),
-    rustc_const_unstable(feature = "const_atomic_usize_new"),
     stable(feature = "extended_compare_and_swap", since = "1.10.0"),
     stable(feature = "atomic_debug", since = "1.3.0"),
     stable(feature = "atomic_access", since = "1.15.0"),
+    "usize", "../../../std/primitive.usize.html",
     usize AtomicUsize ATOMIC_USIZE_INIT
 }
 
@@ -1752,7 +1789,7 @@ pub fn fence(order: Ordering) {
 /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed
 /// [memory barriers]: https://www.kernel.org/doc/Documentation/memory-barriers.txt
 #[inline]
-#[stable(feature = "compiler_fences", since = "1.22.0")]
+#[stable(feature = "compiler_fences", since = "1.21.0")]
 pub fn compiler_fence(order: Ordering) {
     unsafe {
         match order {
diff --git a/src/libcore/tests/array.rs b/src/libcore/tests/array.rs
index 6af031dee58..6278d5e23e0 100644
--- a/src/libcore/tests/array.rs
+++ b/src/libcore/tests/array.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 use core::array::FixedSizeArray;
+use core::convert::TryFrom;
 
 #[test]
 fn fixed_size_array() {
@@ -26,3 +27,25 @@ fn fixed_size_array() {
     assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_array).len(), 0);
     assert_eq!(FixedSizeArray::as_mut_slice(&mut empty_zero_sized).len(), 0);
 }
+
+#[test]
+fn array_try_from() {
+    macro_rules! test {
+        ($($N:expr)+) => {
+            $({
+                type Array = [u8; $N];
+                let array: Array = [0; $N];
+                let slice: &[u8] = &array[..];
+
+                let result = <&Array>::try_from(slice);
+                assert_eq!(&array, result.unwrap());
+            })+
+        }
+    }
+    test! {
+         0  1  2  3  4  5  6  7  8  9
+        10 11 12 13 14 15 16 17 18 19
+        20 21 22 23 24 25 26 27 28 29
+        30 31 32
+    }
+}
diff --git a/src/libcore/tests/char.rs b/src/libcore/tests/char.rs
index 7c3b90c8153..4e10ceac878 100644
--- a/src/libcore/tests/char.rs
+++ b/src/libcore/tests/char.rs
@@ -32,7 +32,6 @@ fn test_convert() {
 #[test]
 fn test_from_str() {
     assert_eq!(char::from_str("a").unwrap(), 'a');
-    assert_eq!(char::try_from("a").unwrap(), 'a');
     assert_eq!(char::from_str("\0").unwrap(), '\0');
     assert_eq!(char::from_str("\u{D7FF}").unwrap(), '\u{d7FF}');
     assert!(char::from_str("").is_err());
diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs
index e8ea6044f5f..8716421b424 100644
--- a/src/libcore/tests/hash/mod.rs
+++ b/src/libcore/tests/hash/mod.rs
@@ -12,6 +12,7 @@ mod sip;
 
 use std::hash::{Hash, Hasher};
 use std::default::Default;
+use std::rc::Rc;
 
 struct MyHasher {
     hash: u64,
@@ -64,18 +65,28 @@ fn test_writer_hasher() {
     assert_eq!(hash(& s), 97 + 0xFF);
     let s: Box<str> = String::from("a").into_boxed_str();
     assert_eq!(hash(& s), 97 + 0xFF);
+    let s: Rc<&str> = Rc::new("a");
+    assert_eq!(hash(&s), 97 + 0xFF);
     let cs: &[u8] = &[1, 2, 3];
     assert_eq!(hash(& cs), 9);
     let cs: Box<[u8]> = Box::new([1, 2, 3]);
     assert_eq!(hash(& cs), 9);
-
-    // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>
+    let cs: Rc<[u8]> = Rc::new([1, 2, 3]);
+    assert_eq!(hash(& cs), 9);
 
     let ptr = 5_usize as *const i32;
     assert_eq!(hash(&ptr), 5);
 
     let ptr = 5_usize as *mut i32;
     assert_eq!(hash(&ptr), 5);
+
+    let cs: &mut [u8] = &mut [1, 2, 3];
+    let ptr = cs.as_ptr();
+    let slice_ptr = cs as *const [u8];
+    assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
+
+    let slice_ptr = cs as *mut [u8];
+    assert_eq!(hash(&slice_ptr), hash(&ptr) + cs.len() as u64);
 }
 
 struct Custom { hash: u64 }
diff --git a/src/libcore/tests/hash/sip.rs b/src/libcore/tests/hash/sip.rs
index 4a9657e0340..c6dd41798f2 100644
--- a/src/libcore/tests/hash/sip.rs
+++ b/src/libcore/tests/hash/sip.rs
@@ -243,24 +243,22 @@ fn test_siphash_2_4() {
         t += 1;
     }
 }
-#[test] #[cfg(target_arch = "arm")]
+
+#[test]
+#[cfg(target_pointer_width = "32")]
 fn test_hash_usize() {
     let val = 0xdeadbeef_deadbeef_u64;
     assert!(hash(&(val as u64)) != hash(&(val as usize)));
     assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
 }
-#[test] #[cfg(target_arch = "x86_64")]
+
+#[test]
+#[cfg(target_pointer_width = "64")]
 fn test_hash_usize() {
     let val = 0xdeadbeef_deadbeef_u64;
     assert_eq!(hash(&(val as u64)), hash(&(val as usize)));
     assert!(hash(&(val as u32)) != hash(&(val as usize)));
 }
-#[test] #[cfg(target_arch = "x86")]
-fn test_hash_usize() {
-    let val = 0xdeadbeef_deadbeef_u64;
-    assert!(hash(&(val as u64)) != hash(&(val as usize)));
-    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
-}
 
 #[test]
 fn test_hash_idempotent() {
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 3c4ea974fc9..5cac5b26d88 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -249,6 +249,25 @@ fn test_filter_map() {
 }
 
 #[test]
+fn test_filter_map_fold() {
+    let xs = [0, 1, 2, 3, 4, 5, 6, 7, 8];
+    let ys = [0*0, 2*2, 4*4, 6*6, 8*8];
+    let it = xs.iter().filter_map(|&x| if x % 2 == 0 { Some(x*x) } else { None });
+    let i = it.fold(0, |i, x| {
+        assert_eq!(x, ys[i]);
+        i + 1
+    });
+    assert_eq!(i, ys.len());
+
+    let it = xs.iter().filter_map(|&x| if x % 2 == 0 { Some(x*x) } else { None });
+    let i = it.rfold(ys.len(), |i, x| {
+        assert_eq!(x, ys[i - 1]);
+        i - 1
+    });
+    assert_eq!(i, 0);
+}
+
+#[test]
 fn test_iterator_enumerate() {
     let xs = [0, 1, 2, 3, 4, 5];
     let it = xs.iter().enumerate();
@@ -282,7 +301,31 @@ fn test_iterator_enumerate_nth() {
 #[test]
 fn test_iterator_enumerate_count() {
     let xs = [0, 1, 2, 3, 4, 5];
-    assert_eq!(xs.iter().count(), 6);
+    assert_eq!(xs.iter().enumerate().count(), 6);
+}
+
+#[test]
+fn test_iterator_enumerate_fold() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().enumerate();
+    // steal a couple to get an interesting offset
+    assert_eq!(it.next(), Some((0, &0)));
+    assert_eq!(it.next(), Some((1, &1)));
+    let i = it.fold(2, |i, (j, &x)| {
+        assert_eq!(i, j);
+        assert_eq!(x, xs[j]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+
+    let mut it = xs.iter().enumerate();
+    assert_eq!(it.next(), Some((0, &0)));
+    let i = it.rfold(xs.len() - 1, |i, (j, &x)| {
+        assert_eq!(i, j);
+        assert_eq!(x, xs[j]);
+        i - 1
+    });
+    assert_eq!(i, 0);
 }
 
 #[test]
@@ -292,6 +335,25 @@ fn test_iterator_filter_count() {
 }
 
 #[test]
+fn test_iterator_filter_fold() {
+    let xs = [0, 1, 2, 3, 4, 5, 6, 7, 8];
+    let ys = [0, 2, 4, 6, 8];
+    let it = xs.iter().filter(|&&x| x % 2 == 0);
+    let i = it.fold(0, |i, &x| {
+        assert_eq!(x, ys[i]);
+        i + 1
+    });
+    assert_eq!(i, ys.len());
+
+    let it = xs.iter().filter(|&&x| x % 2 == 0);
+    let i = it.rfold(ys.len(), |i, &x| {
+        assert_eq!(x, ys[i - 1]);
+        i - 1
+    });
+    assert_eq!(i, 0);
+}
+
+#[test]
 fn test_iterator_peekable() {
     let xs = vec![0, 1, 2, 3, 4, 5];
     let mut it = xs.iter().cloned().peekable();
@@ -381,6 +443,18 @@ fn test_iterator_peekable_last() {
     assert_eq!(it.last(), None);
 }
 
+#[test]
+fn test_iterator_peekable_fold() {
+    let xs = [0, 1, 2, 3, 4, 5];
+    let mut it = xs.iter().peekable();
+    assert_eq!(it.peek(), Some(&&0));
+    let i = it.fold(0, |i, &x| {
+        assert_eq!(x, xs[i]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+}
+
 /// This is an iterator that follows the Iterator contract,
 /// but it is not fused. After having returned None once, it will start
 /// producing elements if .next() is called again.
@@ -471,6 +545,26 @@ fn test_iterator_skip_while() {
 }
 
 #[test]
+fn test_iterator_skip_while_fold() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
+    let ys = [15, 16, 17, 19];
+    let it = xs.iter().skip_while(|&x| *x < 15);
+    let i = it.fold(0, |i, &x| {
+        assert_eq!(x, ys[i]);
+        i + 1
+    });
+    assert_eq!(i, ys.len());
+
+    let mut it = xs.iter().skip_while(|&x| *x < 15);
+    assert_eq!(it.next(), Some(&ys[0])); // process skips before folding
+    let i = it.fold(1, |i, &x| {
+        assert_eq!(x, ys[i]);
+        i + 1
+    });
+    assert_eq!(i, ys.len());
+}
+
+#[test]
 fn test_iterator_skip() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
     let ys = [13, 15, 16, 17, 19, 20, 30];
@@ -567,6 +661,45 @@ fn test_iterator_skip_last() {
 }
 
 #[test]
+fn test_iterator_skip_fold() {
+    let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
+    let ys = [13, 15, 16, 17, 19, 20, 30];
+
+    let it = xs.iter().skip(5);
+    let i = it.fold(0, |i, &x| {
+        assert_eq!(x, ys[i]);
+        i + 1
+    });
+    assert_eq!(i, ys.len());
+
+    let mut it = xs.iter().skip(5);
+    assert_eq!(it.next(), Some(&ys[0])); // process skips before folding
+    let i = it.fold(1, |i, &x| {
+        assert_eq!(x, ys[i]);
+        i + 1
+    });
+    assert_eq!(i, ys.len());
+
+    let it = xs.iter().skip(5);
+    let i = it.rfold(ys.len(), |i, &x| {
+        let i = i - 1;
+        assert_eq!(x, ys[i]);
+        i
+    });
+    assert_eq!(i, 0);
+
+    let mut it = xs.iter().skip(5);
+    assert_eq!(it.next(), Some(&ys[0])); // process skips before folding
+    let i = it.rfold(ys.len(), |i, &x| {
+        let i = i - 1;
+        assert_eq!(x, ys[i]);
+        i
+    });
+    assert_eq!(i, 1);
+
+}
+
+#[test]
 fn test_iterator_take() {
     let xs = [0, 1, 2, 3, 5, 13, 15, 16, 17, 19];
     let ys = [0, 1, 2, 3, 5];
@@ -661,13 +794,22 @@ fn test_iterator_flat_map_fold() {
     let xs = [0, 3, 6];
     let ys = [1, 2, 3, 4, 5, 6, 7];
     let mut it = xs.iter().flat_map(|&x| x..x+3);
-    it.next();
-    it.next_back();
+    assert_eq!(it.next(), Some(0));
+    assert_eq!(it.next_back(), Some(8));
     let i = it.fold(0, |i, x| {
         assert_eq!(x, ys[i]);
         i + 1
     });
     assert_eq!(i, ys.len());
+
+    let mut it = xs.iter().flat_map(|&x| x..x+3);
+    assert_eq!(it.next(), Some(0));
+    assert_eq!(it.next_back(), Some(8));
+    let i = it.rfold(ys.len(), |i, x| {
+        assert_eq!(x, ys[i - 1]);
+        i - 1
+    });
+    assert_eq!(i, 0);
 }
 
 #[test]
@@ -685,6 +827,32 @@ fn test_inspect() {
 }
 
 #[test]
+fn test_inspect_fold() {
+    let xs = [1, 2, 3, 4];
+    let mut n = 0;
+    {
+        let it = xs.iter().inspect(|_| n += 1);
+        let i = it.fold(0, |i, &x| {
+            assert_eq!(x, xs[i]);
+            i + 1
+        });
+        assert_eq!(i, xs.len());
+    }
+    assert_eq!(n, xs.len());
+
+    let mut n = 0;
+    {
+        let it = xs.iter().inspect(|_| n += 1);
+        let i = it.rfold(xs.len(), |i, &x| {
+            assert_eq!(x, xs[i - 1]);
+            i - 1
+        });
+        assert_eq!(i, 0);
+    }
+    assert_eq!(n, xs.len());
+}
+
+#[test]
 fn test_cycle() {
     let cycle_len = 3;
     let it = (0..).step_by(1).take(cycle_len).cycle();
@@ -1242,6 +1410,31 @@ fn test_fuse_count() {
 }
 
 #[test]
+fn test_fuse_fold() {
+    let xs = [0, 1, 2];
+    let it = xs.iter(); // `FusedIterator`
+    let i = it.fuse().fold(0, |i, &x| {
+        assert_eq!(x, xs[i]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+
+    let it = xs.iter(); // `FusedIterator`
+    let i = it.fuse().rfold(xs.len(), |i, &x| {
+        assert_eq!(x, xs[i - 1]);
+        i - 1
+    });
+    assert_eq!(i, 0);
+
+    let it = xs.iter().scan((), |_, &x| Some(x)); // `!FusedIterator`
+    let i = it.fuse().fold(0, |i, x| {
+        assert_eq!(x, xs[i]);
+        i + 1
+    });
+    assert_eq!(i, xs.len());
+}
+
+#[test]
 fn test_once() {
     let mut it = once(42);
     assert_eq!(it.next(), Some(42));
@@ -1304,3 +1497,207 @@ fn test_step_replace_no_between() {
     assert_eq!(x, 1);
     assert_eq!(y, 5);
 }
+
+#[test]
+fn test_rev_try_folds() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((1..10).rev().try_fold(7, f), (1..10).try_rfold(7, f));
+    assert_eq!((1..10).rev().try_rfold(7, f), (1..10).try_fold(7, f));
+
+    let a = [10, 20, 30, 40, 100, 60, 70, 80, 90];
+    let mut iter = a.iter().rev();
+    assert_eq!(iter.try_fold(0_i8, |acc, &x| acc.checked_add(x)), None);
+    assert_eq!(iter.next(), Some(&70));
+    let mut iter = a.iter().rev();
+    assert_eq!(iter.try_rfold(0_i8, |acc, &x| acc.checked_add(x)), None);
+    assert_eq!(iter.next_back(), Some(&60));
+}
+
+#[test]
+fn test_cloned_try_folds() {
+    let a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    let f_ref = &|acc, &x| i32::checked_add(2*acc, x);
+    assert_eq!(a.iter().cloned().try_fold(7, f), a.iter().try_fold(7, f_ref));
+    assert_eq!(a.iter().cloned().try_rfold(7, f), a.iter().try_rfold(7, f_ref));
+
+    let a = [10, 20, 30, 40, 100, 60, 70, 80, 90];
+    let mut iter = a.iter().cloned();
+    assert_eq!(iter.try_fold(0_i8, |acc, x| acc.checked_add(x)), None);
+    assert_eq!(iter.next(), Some(60));
+    let mut iter = a.iter().cloned();
+    assert_eq!(iter.try_rfold(0_i8, |acc, x| acc.checked_add(x)), None);
+    assert_eq!(iter.next_back(), Some(70));
+}
+
+#[test]
+fn test_chain_try_folds() {
+    let c = || (0..10).chain(10..20);
+
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!(c().try_fold(7, f), (0..20).try_fold(7, f));
+    assert_eq!(c().try_rfold(7, f), (0..20).rev().try_fold(7, f));
+
+    let mut iter = c();
+    assert_eq!(iter.position(|x| x == 5), Some(5));
+    assert_eq!(iter.next(), Some(6), "stopped in front, state Both");
+    assert_eq!(iter.position(|x| x == 13), Some(6));
+    assert_eq!(iter.next(), Some(14), "stopped in back, state Back");
+    assert_eq!(iter.try_fold(0, |acc, x| Some(acc+x)), Some((15..20).sum()));
+
+    let mut iter = c().rev(); // use rev to access try_rfold
+    assert_eq!(iter.position(|x| x == 15), Some(4));
+    assert_eq!(iter.next(), Some(14), "stopped in back, state Both");
+    assert_eq!(iter.position(|x| x == 5), Some(8));
+    assert_eq!(iter.next(), Some(4), "stopped in front, state Front");
+    assert_eq!(iter.try_fold(0, |acc, x| Some(acc+x)), Some((0..4).sum()));
+
+    let mut iter = c();
+    iter.by_ref().rev().nth(14); // skip the last 15, ending in state Front
+    assert_eq!(iter.try_fold(7, f), (0..5).try_fold(7, f));
+
+    let mut iter = c();
+    iter.nth(14); // skip the first 15, ending in state Back
+    assert_eq!(iter.try_rfold(7, f), (15..20).try_rfold(7, f));
+}
+
+#[test]
+fn test_map_try_folds() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((0..10).map(|x| x+3).try_fold(7, f), (3..13).try_fold(7, f));
+    assert_eq!((0..10).map(|x| x+3).try_rfold(7, f), (3..13).try_rfold(7, f));
+
+    let mut iter = (0..40).map(|x| x+10);
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(20));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(46));
+}
+
+#[test]
+fn test_filter_try_folds() {
+    fn p(&x: &i32) -> bool { 0 <= x && x < 10 }
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((-10..20).filter(p).try_fold(7, f), (0..10).try_fold(7, f));
+    assert_eq!((-10..20).filter(p).try_rfold(7, f), (0..10).try_rfold(7, f));
+
+    let mut iter = (0..40).filter(|&x| x % 2 == 1);
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(25));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(31));
+}
+
+#[test]
+fn test_filter_map_try_folds() {
+    let mp = &|x| if 0 <= x && x < 10 { Some(x*2) } else { None };
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((-9..20).filter_map(mp).try_fold(7, f), (0..10).map(|x| 2*x).try_fold(7, f));
+    assert_eq!((-9..20).filter_map(mp).try_rfold(7, f), (0..10).map(|x| 2*x).try_rfold(7, f));
+
+    let mut iter = (0..40).filter_map(|x| if x%2 == 1 { None } else { Some(x*2 + 10) });
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(38));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(78));
+}
+
+#[test]
+fn test_enumerate_try_folds() {
+    let f = &|acc, (i, x)| usize::checked_add(2*acc, x/(i+1) + i);
+    assert_eq!((9..18).enumerate().try_fold(7, f), (0..9).map(|i| (i, i+9)).try_fold(7, f));
+    assert_eq!((9..18).enumerate().try_rfold(7, f), (0..9).map(|i| (i, i+9)).try_rfold(7, f));
+
+    let mut iter = (100..200).enumerate();
+    let f = &|acc, (i, x)| u8::checked_add(acc, u8::checked_div(x, i as u8 + 1)?);
+    assert_eq!(iter.try_fold(0, f), None);
+    assert_eq!(iter.next(), Some((7, 107)));
+    assert_eq!(iter.try_rfold(0, f), None);
+    assert_eq!(iter.next_back(), Some((11, 111)));
+}
+
+#[test]
+fn test_peek_try_fold() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((1..20).peekable().try_fold(7, f), (1..20).try_fold(7, f));
+    let mut iter = (1..20).peekable();
+    assert_eq!(iter.peek(), Some(&1));
+    assert_eq!(iter.try_fold(7, f), (1..20).try_fold(7, f));
+
+    let mut iter = [100, 20, 30, 40, 50, 60, 70].iter().cloned().peekable();
+    assert_eq!(iter.peek(), Some(&100));
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.peek(), Some(&40));
+}
+
+#[test]
+fn test_skip_while_try_fold() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    fn p(&x: &i32) -> bool { (x % 10) <= 5 }
+    assert_eq!((1..20).skip_while(p).try_fold(7, f), (6..20).try_fold(7, f));
+    let mut iter = (1..20).skip_while(p);
+    assert_eq!(iter.nth(5), Some(11));
+    assert_eq!(iter.try_fold(7, f), (12..20).try_fold(7, f));
+
+    let mut iter = (0..50).skip_while(|&x| (x % 20) < 15);
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(23));
+}
+
+#[test]
+fn test_take_while_folds() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((1..20).take_while(|&x| x != 10).try_fold(7, f), (1..10).try_fold(7, f));
+    let mut iter = (1..20).take_while(|&x| x != 10);
+    assert_eq!(iter.try_fold(0, |x, y| Some(x+y)), Some((1..10).sum()));
+    assert_eq!(iter.next(), None, "flag should be set");
+    let iter = (1..20).take_while(|&x| x != 10);
+    assert_eq!(iter.fold(0, |x, y| x+y), (1..10).sum());
+
+    let mut iter = (10..50).take_while(|&x| x != 40);
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(20));
+}
+
+#[test]
+fn test_skip_try_folds() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((1..20).skip(9).try_fold(7, f), (10..20).try_fold(7, f));
+    assert_eq!((1..20).skip(9).try_rfold(7, f), (10..20).try_rfold(7, f));
+
+    let mut iter = (0..30).skip(10);
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(20));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(24));
+}
+
+#[test]
+fn test_take_try_folds() {
+    let f = &|acc, x| i32::checked_add(2*acc, x);
+    assert_eq!((10..30).take(10).try_fold(7, f), (10..20).try_fold(7, f));
+    //assert_eq!((10..30).take(10).try_rfold(7, f), (10..20).try_rfold(7, f));
+
+    let mut iter = (10..30).take(20);
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(20));
+    //assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    //assert_eq!(iter.next_back(), Some(24));
+}
+
+#[test]
+fn test_flat_map_try_folds() {
+    let f = &|acc, x| i32::checked_add(acc*2/3, x);
+    let mr = &|x| (5*x)..(5*x + 5);
+    assert_eq!((0..10).flat_map(mr).try_fold(7, f), (0..50).try_fold(7, f));
+    assert_eq!((0..10).flat_map(mr).try_rfold(7, f), (0..50).try_rfold(7, f));
+    let mut iter = (0..10).flat_map(mr);
+    iter.next(); iter.next_back(); // have front and back iters in progress
+    assert_eq!(iter.try_rfold(7, f), (1..49).try_rfold(7, f));
+
+    let mut iter = (0..10).flat_map(|x| (4*x)..(4*x + 4));
+    assert_eq!(iter.try_fold(0, i8::checked_add), None);
+    assert_eq!(iter.next(), Some(17));
+    assert_eq!(iter.try_rfold(0, i8::checked_add), None);
+    assert_eq!(iter.next_back(), Some(35));
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 47995597a0a..0e445cdac35 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -24,9 +24,10 @@
 #![feature(i128_type)]
 #![feature(inclusive_range)]
 #![feature(inclusive_range_syntax)]
+#![feature(iterator_try_fold)]
 #![feature(iter_rfind)]
+#![feature(iter_rfold)]
 #![feature(nonzero)]
-#![feature(rand)]
 #![feature(raw)]
 #![feature(refcell_replace_swap)]
 #![feature(sip_hash_13)]
@@ -38,15 +39,11 @@
 #![feature(test)]
 #![feature(trusted_len)]
 #![feature(try_from)]
+#![feature(try_trait)]
 #![feature(unique)]
 
-#![feature(const_atomic_bool_new)]
-#![feature(const_atomic_usize_new)]
-#![feature(const_atomic_isize_new)]
-
 extern crate core;
 extern crate test;
-extern crate rand;
 
 mod any;
 mod array;
diff --git a/src/libcore/tests/mem.rs b/src/libcore/tests/mem.rs
index 86e59c736ba..f55a1c81463 100644
--- a/src/libcore/tests/mem.rs
+++ b/src/libcore/tests/mem.rs
@@ -121,3 +121,19 @@ fn test_transmute() {
     }
 }
 
+#[test]
+#[allow(dead_code)]
+fn test_discriminant_send_sync() {
+    enum Regular {
+        A,
+        B(i32)
+    }
+    enum NotSendSync {
+        A(*const i32)
+    }
+
+    fn is_send_sync<T: Send + Sync>() { }
+
+    is_send_sync::<Discriminant<Regular>>();
+    is_send_sync::<Discriminant<NotSendSync>>();
+}
diff --git a/src/libcore/tests/num/flt2dec/estimator.rs b/src/libcore/tests/num/flt2dec/estimator.rs
index 0bca616ea9a..857aae72c8a 100644
--- a/src/libcore/tests/num/flt2dec/estimator.rs
+++ b/src/libcore/tests/num/flt2dec/estimator.rs
@@ -8,11 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// FIXME https://github.com/kripken/emscripten/issues/4563
-// NB we have to actually not compile this test to avoid
-// an undefined symbol error
-#![cfg(not(target_os = "emscripten"))]
-
 use core::num::flt2dec::estimator::*;
 
 #[test]
diff --git a/src/libcore/tests/num/flt2dec/mod.rs b/src/libcore/tests/num/flt2dec/mod.rs
index 0f4d19e7092..ef0178815f9 100644
--- a/src/libcore/tests/num/flt2dec/mod.rs
+++ b/src/libcore/tests/num/flt2dec/mod.rs
@@ -9,10 +9,7 @@
 // except according to those terms.
 
 use std::prelude::v1::*;
-use std::{str, mem, i16, f32, f64, fmt};
-use std::__rand as rand;
-use rand::{Rand, XorShiftRng};
-use rand::distributions::{IndependentSample, Range};
+use std::{str, i16, f32, f64, fmt};
 
 use core::num::flt2dec::{decode, DecodableFloat, FullDecoded, Decoded};
 use core::num::flt2dec::{MAX_SIG_DIGITS, round_up, Part, Formatted, Sign};
@@ -464,87 +461,6 @@ pub fn more_shortest_sanity_test<F>(mut f: F) where F: FnMut(&Decoded, &mut [u8]
                       exp: 0, inclusive: false} => b"99999999999999999", 17);
 }
 
-fn iterate<F, G, V>(func: &str, k: usize, n: usize, mut f: F, mut g: G, mut v: V) -> (usize, usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16),
-              V: FnMut(usize) -> Decoded {
-    assert!(k <= 1024);
-
-    let mut npassed = 0; // f(x) = Some(g(x))
-    let mut nignored = 0; // f(x) = None
-
-    for i in 0..n {
-        if (i & 0xfffff) == 0 {
-            println!("in progress, {:x}/{:x} (ignored={} passed={} failed={})",
-                     i, n, nignored, npassed, i - nignored - npassed);
-        }
-
-        let decoded = v(i);
-        let mut buf1 = [0; 1024];
-        if let Some((len1, e1)) = f(&decoded, &mut buf1[..k]) {
-            let mut buf2 = [0; 1024];
-            let (len2, e2) = g(&decoded, &mut buf2[..k]);
-            if e1 == e2 && &buf1[..len1] == &buf2[..len2] {
-                npassed += 1;
-            } else {
-                println!("equivalence test failed, {:x}/{:x}: {:?} f(i)={}e{} g(i)={}e{}",
-                         i, n, decoded, str::from_utf8(&buf1[..len1]).unwrap(), e1,
-                                        str::from_utf8(&buf2[..len2]).unwrap(), e2);
-            }
-        } else {
-            nignored += 1;
-        }
-    }
-    println!("{}({}): done, ignored={} passed={} failed={}",
-             func, k, nignored, npassed, n - nignored - npassed);
-    assert!(nignored + npassed == n,
-            "{}({}): {} out of {} values returns an incorrect value!",
-            func, k, n - nignored - npassed, n);
-    (npassed, nignored)
-}
-
-pub fn f32_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
-    let f32_range = Range::new(0x0000_0001u32, 0x7f80_0000);
-    iterate("f32_random_equivalence_test", k, n, f, g, |_| {
-        let i: u32 = f32_range.ind_sample(&mut rng);
-        let x: f32 = unsafe {mem::transmute(i)};
-        decode_finite(x)
-    });
-}
-
-pub fn f64_random_equivalence_test<F, G>(f: F, g: G, k: usize, n: usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    let mut rng: XorShiftRng = Rand::rand(&mut rand::thread_rng());
-    let f64_range = Range::new(0x0000_0000_0000_0001u64, 0x7ff0_0000_0000_0000);
-    iterate("f64_random_equivalence_test", k, n, f, g, |_| {
-        let i: u64 = f64_range.ind_sample(&mut rng);
-        let x: f64 = unsafe {mem::transmute(i)};
-        decode_finite(x)
-    });
-}
-
-pub fn f32_exhaustive_equivalence_test<F, G>(f: F, g: G, k: usize)
-        where F: FnMut(&Decoded, &mut [u8]) -> Option<(usize, i16)>,
-              G: FnMut(&Decoded, &mut [u8]) -> (usize, i16) {
-    // we have only 2^23 * (2^8 - 1) - 1 = 2,139,095,039 positive finite f32 values,
-    // so why not simply testing all of them?
-    //
-    // this is of course very stressful (and thus should be behind an `#[ignore]` attribute),
-    // but with `-C opt-level=3 -C lto` this only takes about an hour or so.
-
-    // iterate from 0x0000_0001 to 0x7f7f_ffff, i.e. all finite ranges
-    let (npassed, nignored) = iterate("f32_exhaustive_equivalence_test",
-                                      k, 0x7f7f_ffff, f, g, |i: usize| {
-        let x: f32 = unsafe {mem::transmute(i as u32 + 1)};
-        decode_finite(x)
-    });
-    assert_eq!((npassed, nignored), (2121451881, 17643158));
-}
-
 fn to_string_with_parts<F>(mut f: F) -> String
         where F: for<'a> FnMut(&'a mut [u8], &'a mut [Part<'a>]) -> Formatted<'a> {
     let mut buf = [0; 1024];
diff --git a/src/libcore/tests/num/flt2dec/strategy/grisu.rs b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
index 17fb99bcc92..286b39d8cf3 100644
--- a/src/libcore/tests/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/tests/num/flt2dec/strategy/grisu.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::i16;
 use super::super::*;
 use core::num::flt2dec::strategy::grisu::*;
 
@@ -47,35 +46,6 @@ fn shortest_sanity_test() {
 }
 
 #[test]
-fn shortest_random_equivalence_test() {
-    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
-    f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, 10_000);
-}
-
-#[test] #[ignore] // it is too expensive
-fn shortest_f32_exhaustive_equivalence_test() {
-    // it is hard to directly test the optimality of the output, but we can at least test if
-    // two different algorithms agree to each other.
-    //
-    // this reports the progress and the number of f32 values returned `None`.
-    // with `--nocapture` (and plenty of time and appropriate rustc flags), this should print:
-    // `done, ignored=17643158 passed=2121451881 failed=0`.
-
-    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f32_exhaustive_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS);
-}
-
-#[test] #[ignore] // it is too expensive
-fn shortest_f64_hard_random_equivalence_test() {
-    // this again probably has to use appropriate rustc flags.
-
-    use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
-    f64_random_equivalence_test(format_shortest_opt, fallback,
-                                         MAX_SIG_DIGITS, 100_000_000);
-}
-
-#[test]
 fn exact_sanity_test() {
     // See comments in dragon.rs's exact_sanity_test for why this test is
     // ignored on MSVC
@@ -86,24 +56,6 @@ fn exact_sanity_test() {
 }
 
 #[test]
-fn exact_f32_random_equivalence_test() {
-    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
-    for k in 1..21 {
-        f32_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
-                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
-    }
-}
-
-#[test]
-fn exact_f64_random_equivalence_test() {
-    use core::num::flt2dec::strategy::dragon::format_exact as fallback;
-    for k in 1..21 {
-        f64_random_equivalence_test(|d, buf| format_exact_opt(d, buf, i16::MIN),
-                                             |d, buf| fallback(d, buf, i16::MIN), k, 1_000);
-    }
-}
-
-#[test]
 fn test_to_shortest_str() {
     to_shortest_str_test(format_shortest);
 }
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
index 400d53ce51a..7eb5ff98857 100644
--- a/src/libcore/tests/num/mod.rs
+++ b/src/libcore/tests/num/mod.rs
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::convert::TryFrom;
+use core::convert::{TryFrom, TryInto};
 use core::cmp::PartialEq;
 use core::fmt::Debug;
 use core::marker::Copy;
+use core::num::TryFromIntError;
 use core::ops::{Add, Sub, Mul, Div, Rem};
 use core::option::Option;
 use core::option::Option::{Some, None};
@@ -134,6 +135,13 @@ fn test_empty() {
     assert_eq!("".parse::<u8>().ok(), None);
 }
 
+#[test]
+fn test_infallible_try_from_int_error() {
+    let func = |x: i8| -> Result<i32, TryFromIntError> { Ok(x.try_into()?) };
+
+    assert!(func(0).is_ok());
+}
+
 macro_rules! test_impl_from {
     ($fn_name: ident, $Small: ty, $Large: ty) => {
         #[test]
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index 6bac55575fb..22109e28edd 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -270,3 +270,30 @@ fn test_cloned() {
     assert_eq!(opt_ref_ref.clone().cloned(), Some(&val));
     assert_eq!(opt_ref_ref.cloned().cloned(), Some(1));
 }
+
+#[test]
+fn test_try() {
+    fn try_option_some() -> Option<u8> {
+        let val = Some(1)?;
+        Some(val)
+    }
+    assert_eq!(try_option_some(), Some(1));
+
+    fn try_option_none() -> Option<u8> {
+        let val = None?;
+        Some(val)
+    }
+    assert_eq!(try_option_none(), None);
+
+    fn try_option_ok() -> Result<u8, NoneError> {
+        let val = Some(1)?;
+        Ok(val)
+    }
+    assert_eq!(try_option_ok(), Ok(1));
+
+    fn try_option_err() -> Result<u8, NoneError> {
+        let val = None?;
+        Ok(val)
+    }
+    assert_eq!(try_option_err(), Err(NoneError));
+}
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index c2d53840f8f..98436f0e1d1 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -62,6 +62,39 @@ fn test_is_null() {
 
     let mq = unsafe { mp.offset(1) };
     assert!(!mq.is_null());
+
+    // Pointers to unsized types -- slices
+    let s: &mut [u8] = &mut [1, 2, 3];
+    let cs: *const [u8] = s;
+    assert!(!cs.is_null());
+
+    let ms: *mut [u8] = s;
+    assert!(!ms.is_null());
+
+    let cz: *const [u8] = &[];
+    assert!(!cz.is_null());
+
+    let mz: *mut [u8] = &mut [];
+    assert!(!mz.is_null());
+
+    let ncs: *const [u8] = null::<[u8; 3]>();
+    assert!(ncs.is_null());
+
+    let nms: *mut [u8] = null_mut::<[u8; 3]>();
+    assert!(nms.is_null());
+
+    // Pointers to unsized types -- trait objects
+    let ci: *const ToString = &3;
+    assert!(!ci.is_null());
+
+    let mi: *mut ToString = &mut 3;
+    assert!(!mi.is_null());
+
+    let nci: *const ToString = null::<isize>();
+    assert!(nci.is_null());
+
+    let nmi: *mut ToString = null_mut::<isize>();
+    assert!(nmi.is_null());
 }
 
 #[test]
@@ -85,6 +118,39 @@ fn test_as_ref() {
             let p = &u as *const isize;
             assert_eq!(p.as_ref().unwrap(), &2);
         }
+
+        // Pointers to unsized types -- slices
+        let s: &mut [u8] = &mut [1, 2, 3];
+        let cs: *const [u8] = s;
+        assert_eq!(cs.as_ref(), Some(&*s));
+
+        let ms: *mut [u8] = s;
+        assert_eq!(ms.as_ref(), Some(&*s));
+
+        let cz: *const [u8] = &[];
+        assert_eq!(cz.as_ref(), Some(&[][..]));
+
+        let mz: *mut [u8] = &mut [];
+        assert_eq!(mz.as_ref(), Some(&[][..]));
+
+        let ncs: *const [u8] = null::<[u8; 3]>();
+        assert_eq!(ncs.as_ref(), None);
+
+        let nms: *mut [u8] = null_mut::<[u8; 3]>();
+        assert_eq!(nms.as_ref(), None);
+
+        // Pointers to unsized types -- trait objects
+        let ci: *const ToString = &3;
+        assert!(ci.as_ref().is_some());
+
+        let mi: *mut ToString = &mut 3;
+        assert!(mi.as_ref().is_some());
+
+        let nci: *const ToString = null::<isize>();
+        assert!(nci.as_ref().is_none());
+
+        let nmi: *mut ToString = null_mut::<isize>();
+        assert!(nmi.as_ref().is_none());
     }
 }
 
@@ -103,6 +169,24 @@ fn test_as_mut() {
             let p = &mut u as *mut isize;
             assert!(p.as_mut().unwrap() == &mut 2);
         }
+
+        // Pointers to unsized types -- slices
+        let s: &mut [u8] = &mut [1, 2, 3];
+        let ms: *mut [u8] = s;
+        assert_eq!(ms.as_mut(), Some(s));
+
+        let mz: *mut [u8] = &mut [];
+        assert_eq!(mz.as_mut(), Some(&mut [][..]));
+
+        let nms: *mut [u8] = null_mut::<[u8; 3]>();
+        assert_eq!(nms.as_mut(), None);
+
+        // Pointers to unsized types -- trait objects
+        let mi: *mut ToString = &mut 3;
+        assert!(mi.as_mut().is_some());
+
+        let nmi: *mut ToString = null_mut::<isize>();
+        assert!(nmi.as_mut().is_none());
     }
 }
 
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index 4c5f19dee12..ce41bde8342 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::option::*;
+
 fn op1() -> Result<isize, &'static str> { Ok(666) }
 fn op2() -> Result<isize, &'static str> { Err("sadface") }
 
@@ -202,3 +204,30 @@ pub fn test_unwrap_or_default() {
     assert_eq!(op1().unwrap_or_default(), 666);
     assert_eq!(op2().unwrap_or_default(), 0);
 }
+
+#[test]
+fn test_try() {
+    fn try_result_some() -> Option<u8> {
+        let val = Ok(1)?;
+        Some(val)
+    }
+    assert_eq!(try_result_some(), Some(1));
+
+    fn try_result_none() -> Option<u8> {
+        let val = Err(NoneError)?;
+        Some(val)
+    }
+    assert_eq!(try_result_none(), None);
+
+    fn try_result_ok() -> Result<u8, u8> {
+        let val = Ok(1)?;
+        Ok(val)
+    }
+    assert_eq!(try_result_ok(), Ok(1));
+
+    fn try_result_err() -> Result<u8, u8> {
+        let val = Err(1)?;
+        Ok(val)
+    }
+    assert_eq!(try_result_err(), Err(1));
+}
diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs
index 8c31d2e83d3..fa4c2e9b373 100644
--- a/src/libcore/tests/slice.rs
+++ b/src/libcore/tests/slice.rs
@@ -8,29 +8,63 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::cmp::Ordering::{Equal, Greater, Less};
-use core::slice::heapsort;
 use core::result::Result::{Ok, Err};
-use rand::{Rng, XorShiftRng};
 
 #[test]
 fn test_binary_search() {
+    let b: [i32; 0] = [];
+    assert_eq!(b.binary_search(&5), Err(0));
+
+    let b = [4];
+    assert_eq!(b.binary_search(&3), Err(0));
+    assert_eq!(b.binary_search(&4), Ok(0));
+    assert_eq!(b.binary_search(&5), Err(1));
+
     let b = [1, 2, 4, 6, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
-    assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
-    let b = [1, 2, 4, 6, 7, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3));
-    assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3));
-    let b = [1, 2, 4, 6, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(4));
-    assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(4));
+    assert_eq!(b.binary_search(&5), Err(3));
+    assert_eq!(b.binary_search(&6), Ok(3));
+    assert_eq!(b.binary_search(&7), Err(4));
+    assert_eq!(b.binary_search(&8), Ok(4));
+
+    let b = [1, 2, 4, 5, 6, 8];
+    assert_eq!(b.binary_search(&9), Err(6));
+
     let b = [1, 2, 4, 6, 7, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(5));
+    assert_eq!(b.binary_search(&6), Ok(3));
+    assert_eq!(b.binary_search(&5), Err(3));
+    assert_eq!(b.binary_search(&8), Ok(5));
+
     let b = [1, 2, 4, 5, 6, 8, 9];
-    assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(5));
-    assert!(b.binary_search_by(|v| v.cmp(&0)) == Err(0));
-    let b = [1, 2, 4, 5, 6, 8];
-    assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6));
+    assert_eq!(b.binary_search(&7), Err(5));
+    assert_eq!(b.binary_search(&0), Err(0));
+
+    let b = [1, 3, 3, 3, 7];
+    assert_eq!(b.binary_search(&0), Err(0));
+    assert_eq!(b.binary_search(&1), Ok(0));
+    assert_eq!(b.binary_search(&2), Err(1));
+    assert!(match b.binary_search(&3) { Ok(1...3) => true, _ => false });
+    assert!(match b.binary_search(&3) { Ok(1...3) => true, _ => false });
+    assert_eq!(b.binary_search(&4), Err(4));
+    assert_eq!(b.binary_search(&5), Err(4));
+    assert_eq!(b.binary_search(&6), Err(4));
+    assert_eq!(b.binary_search(&7), Ok(4));
+    assert_eq!(b.binary_search(&8), Err(5));
+}
+
+#[test]
+// Test implementation specific behavior when finding equivalent elements.
+// It is ok to break this test but when you do a crater run is highly advisable.
+fn test_binary_search_implementation_details() {
+    let b = [1, 1, 2, 2, 3, 3, 3];
+    assert_eq!(b.binary_search(&1), Ok(1));
+    assert_eq!(b.binary_search(&2), Ok(3));
+    assert_eq!(b.binary_search(&3), Ok(6));
+    let b = [1, 1, 1, 1, 1, 3, 3, 3, 3];
+    assert_eq!(b.binary_search(&1), Ok(4));
+    assert_eq!(b.binary_search(&3), Ok(8));
+    let b = [1, 1, 1, 1, 3, 3, 3, 3, 3];
+    assert_eq!(b.binary_search(&1), Ok(3));
+    assert_eq!(b.binary_search(&3), Ok(8));
 }
 
 #[test]
@@ -239,6 +273,23 @@ fn test_find_rfind() {
 }
 
 #[test]
+fn test_iter_folds() {
+    let a = [1, 2, 3, 4, 5]; // len>4 so the unroll is used
+    assert_eq!(a.iter().fold(0, |acc, &x| 2*acc + x), 57);
+    assert_eq!(a.iter().rfold(0, |acc, &x| 2*acc + x), 129);
+    let fold = |acc: i32, &x| acc.checked_mul(2)?.checked_add(x);
+    assert_eq!(a.iter().try_fold(0, &fold), Some(57));
+    assert_eq!(a.iter().try_rfold(0, &fold), Some(129));
+
+    // short-circuiting try_fold, through other methods
+    let a = [0, 1, 2, 3, 5, 5, 5, 7, 8, 9];
+    let mut iter = a.iter();
+    assert_eq!(iter.position(|&x| x == 3), Some(3));
+    assert_eq!(iter.rfind(|&&x| x == 5), Some(&5));
+    assert_eq!(iter.len(), 2);
+}
+
+#[test]
 fn test_rotate() {
     const N: usize = 600;
     let a: &mut [_] = &mut [0; N];
@@ -253,68 +304,3 @@ fn test_rotate() {
         assert_eq!(a[(i+k)%N], i);
     }
 }
-
-#[test]
-fn sort_unstable() {
-    let mut v = [0; 600];
-    let mut tmp = [0; 600];
-    let mut rng = XorShiftRng::new_unseeded();
-
-    for len in (2..25).chain(500..510) {
-        let v = &mut v[0..len];
-        let tmp = &mut tmp[0..len];
-
-        for &modulus in &[5, 10, 100, 1000] {
-            for _ in 0..100 {
-                for i in 0..len {
-                    v[i] = rng.gen::<i32>() % modulus;
-                }
-
-                // Sort in default order.
-                tmp.copy_from_slice(v);
-                tmp.sort_unstable();
-                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
-
-                // Sort in ascending order.
-                tmp.copy_from_slice(v);
-                tmp.sort_unstable_by(|a, b| a.cmp(b));
-                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
-
-                // Sort in descending order.
-                tmp.copy_from_slice(v);
-                tmp.sort_unstable_by(|a, b| b.cmp(a));
-                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
-
-                // Test heapsort using `<` operator.
-                tmp.copy_from_slice(v);
-                heapsort(tmp, |a, b| a < b);
-                assert!(tmp.windows(2).all(|w| w[0] <= w[1]));
-
-                // Test heapsort using `>` operator.
-                tmp.copy_from_slice(v);
-                heapsort(tmp, |a, b| a > b);
-                assert!(tmp.windows(2).all(|w| w[0] >= w[1]));
-            }
-        }
-    }
-
-    // Sort using a completely random comparison function.
-    // This will reorder the elements *somehow*, but won't panic.
-    for i in 0..v.len() {
-        v[i] = i as i32;
-    }
-    v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap());
-    v.sort_unstable();
-    for i in 0..v.len() {
-        assert_eq!(v[i], i as i32);
-    }
-
-    // Should not panic.
-    [0i32; 0].sort_unstable();
-    [(); 10].sort_unstable();
-    [(); 100].sort_unstable();
-
-    let mut v = [0xDEADBEEFu64];
-    v.sort_unstable();
-    assert!(v == [0xDEADBEEF]);
-}
diff --git a/src/libcore/unit.rs b/src/libcore/unit.rs
new file mode 100644
index 00000000000..087ddf9688a
--- /dev/null
+++ b/src/libcore/unit.rs
@@ -0,0 +1,31 @@
+// 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.
+
+use iter::FromIterator;
+
+/// Collapses all unit items from an iterator into one.
+///
+/// This is more useful when combined with higher-level abstractions, like
+/// collecting to a `Result<(), E>` where you only care about errors:
+///
+/// ```
+/// use std::io::*;
+/// let data = vec![1, 2, 3, 4, 5];
+/// let res: Result<()> = data.iter()
+///     .map(|x| writeln!(stdout(), "{}", x))
+///     .collect();
+/// assert!(res.is_ok());
+/// ```
+#[stable(feature = "unit_from_iter", since = "1.23.0")]
+impl FromIterator<()> for () {
+    fn from_iter<I: IntoIterator<Item=()>>(iter: I) -> Self {
+        iter.into_iter().for_each(|()| {})
+    }
+}