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/array.rs6
-rw-r--r--src/libcore/cell.rs5
-rw-r--r--src/libcore/char.rs16
-rw-r--r--src/libcore/clone.rs83
-rw-r--r--src/libcore/convert.rs37
-rw-r--r--src/libcore/fmt/mod.rs79
-rw-r--r--src/libcore/fmt/num.rs7
-rw-r--r--src/libcore/hash/mod.rs4
-rw-r--r--src/libcore/heap.rs1075
-rw-r--r--src/libcore/intrinsics.rs10
-rw-r--r--src/libcore/iter/iterator.rs50
-rw-r--r--src/libcore/iter/mod.rs2
-rw-r--r--src/libcore/iter/range.rs75
-rw-r--r--src/libcore/iter/traits.rs25
-rw-r--r--src/libcore/lib.rs7
-rw-r--r--src/libcore/marker.rs56
-rw-r--r--src/libcore/nonzero.rs12
-rw-r--r--src/libcore/num/i128.rs4
-rw-r--r--src/libcore/num/mod.rs250
-rw-r--r--src/libcore/num/u128.rs4
-rw-r--r--src/libcore/ops/drop.rs2
-rw-r--r--src/libcore/ops/generator.rs12
-rw-r--r--src/libcore/ops/mod.rs6
-rw-r--r--src/libcore/ops/place.rs143
-rw-r--r--src/libcore/ops/range.rs264
-rw-r--r--src/libcore/ops/try.rs2
-rw-r--r--src/libcore/option.rs10
-rw-r--r--src/libcore/ptr.rs275
-rw-r--r--src/libcore/str/mod.rs31
-rw-r--r--src/libcore/sync/atomic.rs957
-rw-r--r--src/libcore/tests/ascii.rs3
-rw-r--r--src/libcore/tests/iter.rs27
-rw-r--r--src/libcore/tests/lib.rs9
-rw-r--r--src/libcore/tests/nonzero.rs37
-rw-r--r--src/libcore/tests/num/mod.rs127
35 files changed, 2839 insertions, 873 deletions
diff --git a/src/libcore/array.rs b/src/libcore/array.rs
index 3d24f8902bd..87144c27c9e 100644
--- a/src/libcore/array.rs
+++ b/src/libcore/array.rs
@@ -59,7 +59,7 @@ 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")]
+#[stable(feature = "try_from", since = "1.26.0")]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromSliceError(());
 
@@ -148,7 +148,7 @@ macro_rules! array_impls {
                 }
             }
 
-            #[unstable(feature = "try_from", issue = "33417")]
+            #[stable(feature = "try_from", since = "1.26.0")]
             impl<'a, T> TryFrom<&'a [T]> for &'a [T; $N] {
                 type Error = TryFromSliceError;
 
@@ -162,7 +162,7 @@ macro_rules! array_impls {
                 }
             }
 
-            #[unstable(feature = "try_from", issue = "33417")]
+            #[stable(feature = "try_from", since = "1.26.0")]
             impl<'a, T> TryFrom<&'a mut [T]> for &'a mut [T; $N] {
                 type Error = TryFromSliceError;
 
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index 36618e86968..c8ee166fee3 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -146,13 +146,12 @@
 //!
 //! ```
 //! #![feature(core_intrinsics)]
-//! #![feature(shared)]
 //! use std::cell::Cell;
-//! use std::ptr::Shared;
+//! use std::ptr::NonNull;
 //! use std::intrinsics::abort;
 //!
 //! struct Rc<T: ?Sized> {
-//!     ptr: Shared<RcBox<T>>
+//!     ptr: NonNull<RcBox<T>>
 //! }
 //!
 //! struct RcBox<T: ?Sized> {
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 1638f9710f5..718c6b893ed 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -265,7 +265,7 @@ impl FromStr for char {
 }
 
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl TryFrom<u32> for char {
     type Error = CharTryFromError;
 
@@ -280,11 +280,11 @@ impl TryFrom<u32> for char {
 }
 
 /// The error type returned when a conversion from u32 to char fails.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub struct CharTryFromError(());
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl fmt::Display for CharTryFromError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         "converted integer out of range for `char`".fmt(f)
@@ -902,6 +902,16 @@ impl<I: Iterator<Item = u8>> Iterator for DecodeUtf8<I> {
             }
         })
     }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        let (lower, upper) = self.0.size_hint();
+
+        // A code point is at most 4 bytes long.
+        let min_code_points = lower / 4;
+
+        (min_code_points, upper)
+    }
 }
 
 #[unstable(feature = "decode_utf8", issue = "33906")]
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 826420a0c00..58a8439162c 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -87,6 +87,23 @@
 ///     fn clone(&self) -> Stats { *self }
 /// }
 /// ```
+///
+/// ## Additional implementors
+///
+/// In addition to the [implementors listed below][impls],
+/// the following types also implement `Clone`:
+///
+/// * Function item types (i.e. the distinct types defined for each function)
+/// * Function pointer types (e.g. `fn() -> i32`)
+/// * Array types, for all sizes, if the item type also implements `Clone` (e.g. `[i32; 123456]`)
+/// * Tuple types, if each component also implements `Clone` (e.g. `()`, `(i32, bool)`)
+/// * Closure types, if they capture no value from the environment
+///   or if all such captured values implement `Clone` themselves.
+///   Note that variables captured by shared reference always implement `Clone`
+///   (even if the referent doesn't),
+///   while variables captured by mutable reference never implement `Clone`.
+///
+/// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "clone"]
 pub trait Clone : Sized {
@@ -100,6 +117,7 @@ pub trait Clone : Sized {
     /// assert_eq!("Hello", hello.clone());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "cloning is often expensive and is not expected to have side effects"]
     fn clone(&self) -> Self;
 
     /// Performs copy-assignment from `source`.
@@ -130,3 +148,68 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: ::marker::PhantomData
            reason = "deriving hack, should not be public",
            issue = "0")]
 pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T> }
+
+/// Implementations of `Clone` for primitive types.
+///
+/// Implementations that cannot be described in Rust
+/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+#[cfg(not(stage0))]
+mod impls {
+
+    use super::Clone;
+
+    macro_rules! impl_clone {
+        ($($t:ty)*) => {
+            $(
+                #[stable(feature = "rust1", since = "1.0.0")]
+                impl Clone for $t {
+                    #[inline]
+                    fn clone(&self) -> Self {
+                        *self
+                    }
+                }
+            )*
+        }
+    }
+
+    impl_clone! {
+        usize u8 u16 u32 u64 u128
+        isize i8 i16 i32 i64 i128
+        f32 f64
+        bool char
+    }
+
+    #[stable(feature = "never_type", since = "1.26.0")]
+    impl Clone for ! {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Clone for *const T {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Clone for *mut T {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+    // Shared references can be cloned, but mutable references *cannot*!
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized> Clone for &'a T {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+
+}
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index d3a83dc795c..63721395784 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -48,25 +48,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-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.
 ///
@@ -341,22 +322,26 @@ pub trait From<T>: Sized {
 ///
 /// [`TryFrom`]: trait.TryFrom.html
 /// [`Into`]: trait.Into.html
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 pub trait TryInto<T>: Sized {
     /// The type returned in the event of a conversion error.
+    #[stable(feature = "try_from", since = "1.26.0")]
     type Error;
 
     /// Performs the conversion.
+    #[stable(feature = "try_from", since = "1.26.0")]
     fn try_into(self) -> Result<T, Self::Error>;
 }
 
 /// Attempt to construct `Self` via a conversion.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 pub trait TryFrom<T>: Sized {
     /// The type returned in the event of a conversion error.
+    #[stable(feature = "try_from", since = "1.26.0")]
     type Error;
 
     /// Performs the conversion.
+    #[stable(feature = "try_from", since = "1.26.0")]
     fn try_from(value: T) -> Result<Self, Self::Error>;
 }
 
@@ -382,7 +367,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U>
     }
 }
 
-// FIXME (#23442): replace the above impls for &/&mut with the following more general one:
+// FIXME (#45742): replace the above impls for &/&mut with the following more general one:
 // // As lifts over Deref
 // impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
 //     fn as_ref(&self) -> &U {
@@ -399,7 +384,7 @@ impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U>
     }
 }
 
-// FIXME (#23442): replace the above impl for &mut with the following more general one:
+// FIXME (#45742): replace the above impl for &mut with the following more general one:
 // // AsMut lifts over DerefMut
 // impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
 //     fn as_mut(&mut self) -> &mut U {
@@ -424,7 +409,7 @@ impl<T> From<T> for T {
 
 
 // TryFrom implies TryInto
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl<T, U> TryInto<U> for T where U: TryFrom<T>
 {
     type Error = U::Error;
@@ -436,9 +421,9 @@ 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")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl<T, U> TryFrom<U> for T where T: From<U> {
-    type Error = Infallible;
+    type Error = !;
 
     fn try_from(value: U) -> Result<Self, Self::Error> {
         Ok(T::from(value))
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 3ecd73873c0..d55219d7226 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -401,10 +401,21 @@ impl<'a> Arguments<'a> {
 /// safely be done, so no constructors are given and the fields are private
 /// to prevent modification.
 ///
-/// The [`format_args!`] macro will safely create an instance of this structure
-/// and pass it to a function or closure, passed as the first argument. The
-/// macro validates the format string at compile-time so usage of the [`write`]
-/// and [`format`] functions can be safely performed.
+/// The [`format_args!`] macro will safely create an instance of this structure.
+/// The macro validates the format string at compile-time so usage of the
+/// [`write`] and [`format`] functions can be safely performed.
+///
+/// You can use the `Arguments<'a>` that [`format_args!`] returns in `Debug`
+/// and `Display` contexts as seen below. The example also shows that `Debug`
+/// and `Display` format to the same thing: the interpolated format string
+/// in `format_args!`.
+///
+/// ```rust
+/// let debug = format!("{:?}", format_args!("{} foo {:?}", 1, 2));
+/// let display = format!("{}", format_args!("{} foo {:?}", 1, 2));
+/// assert_eq!("1 foo 2", display);
+/// assert_eq!(display, debug);
+/// ```
 ///
 /// [`format_args!`]: ../../std/macro.format_args.html
 /// [`format`]: ../../std/fmt/fn.format.html
@@ -1553,10 +1564,12 @@ impl<'a> Formatter<'a> {
     ///
     /// ```rust
     /// use std::fmt;
+    /// use std::net::Ipv4Addr;
     ///
     /// struct Foo {
     ///     bar: i32,
     ///     baz: String,
+    ///     addr: Ipv4Addr,
     /// }
     ///
     /// impl fmt::Debug for Foo {
@@ -1564,12 +1577,19 @@ impl<'a> Formatter<'a> {
     ///         fmt.debug_struct("Foo")
     ///             .field("bar", &self.bar)
     ///             .field("baz", &self.baz)
+    ///             .field("addr", &format_args!("{}", self.addr))
     ///             .finish()
     ///     }
     /// }
     ///
-    /// // prints "Foo { bar: 10, baz: "Hello World" }"
-    /// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() });
+    /// assert_eq!(
+    ///     "Foo { bar: 10, baz: \"Hello World\", addr: 127.0.0.1 }",
+    ///     format!("{:?}", Foo {
+    ///         bar: 10,
+    ///         baz: "Hello World".to_string(),
+    ///         addr: Ipv4Addr::new(127, 0, 0, 1),
+    ///     })
+    /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> {
@@ -1583,20 +1603,24 @@ impl<'a> Formatter<'a> {
     ///
     /// ```rust
     /// use std::fmt;
+    /// use std::marker::PhantomData;
     ///
-    /// struct Foo(i32, String);
+    /// struct Foo<T>(i32, String, PhantomData<T>);
     ///
-    /// impl fmt::Debug for Foo {
+    /// impl<T> fmt::Debug for Foo<T> {
     ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     ///         fmt.debug_tuple("Foo")
     ///             .field(&self.0)
     ///             .field(&self.1)
+    ///             .field(&format_args!("_"))
     ///             .finish()
     ///     }
     /// }
     ///
-    /// // prints "Foo(10, "Hello World")"
-    /// println!("{:?}", Foo(10, "Hello World".to_string()));
+    /// assert_eq!(
+    ///     "Foo(10, \"Hello\", _)",
+    ///     format!("{:?}", Foo(10, "Hello".to_string(), PhantomData::<u8>))
+    /// );
     /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> {
@@ -1646,6 +1670,41 @@ impl<'a> Formatter<'a> {
     /// // prints "{10, 11}"
     /// println!("{:?}", Foo(vec![10, 11]));
     /// ```
+    ///
+    /// [`format_args!`]: ../../std/macro.format_args.html
+    ///
+    /// In this more complex example, we use [`format_args!`] and `.debug_set()`
+    /// to build a list of match arms:
+    ///
+    /// ```rust
+    /// use std::fmt;
+    ///
+    /// struct Arm<'a, L: 'a, R: 'a>(&'a (L, R));
+    /// struct Table<'a, K: 'a, V: 'a>(&'a [(K, V)], V);
+    ///
+    /// impl<'a, L, R> fmt::Debug for Arm<'a, L, R>
+    /// where
+    ///     L: 'a + fmt::Debug, R: 'a + fmt::Debug
+    /// {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         L::fmt(&(self.0).0, fmt)?;
+    ///         fmt.write_str(" => ")?;
+    ///         R::fmt(&(self.0).1, fmt)
+    ///     }
+    /// }
+    ///
+    /// impl<'a, K, V> fmt::Debug for Table<'a, K, V>
+    /// where
+    ///     K: 'a + fmt::Debug, V: 'a + fmt::Debug
+    /// {
+    ///     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+    ///         fmt.debug_set()
+    ///         .entries(self.0.iter().map(Arm))
+    ///         .entry(&Arm(&(format_args!("_"), &self.1)))
+    ///         .finish()
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "debug_builders", since = "1.2.0")]
     pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> {
         builders::debug_set_new(self)
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index fcf06ea319d..4451ab445cc 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -63,7 +63,7 @@ trait GenericRadix {
         // characters for a base 2 number.
         let zero = T::zero();
         let is_nonnegative = x >= zero;
-        let mut buf = [0; 128];
+        let mut buf: [u8; 128] = unsafe { mem::uninitialized() };
         let mut curr = buf.len();
         let base = T::from_u8(Self::BASE);
         if is_nonnegative {
@@ -105,10 +105,6 @@ struct Binary;
 #[derive(Clone, PartialEq)]
 struct Octal;
 
-/// A decimal (base 10) radix
-#[derive(Clone, PartialEq)]
-struct Decimal;
-
 /// A hexadecimal (base 16) radix, formatted with lower-case characters
 #[derive(Clone, PartialEq)]
 struct LowerHex;
@@ -134,7 +130,6 @@ macro_rules! radix {
 
 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,
                              x @ 10 ... 15 => b'a' + (x - 10) }
 radix! { UpperHex, 16, "0x", x @  0 ...  9 => b'0' + x,
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index ab714645675..3e1f21cafe4 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -308,7 +308,7 @@ pub trait Hasher {
     }
     /// Writes a single `u128` into this hasher.
     #[inline]
-    #[unstable(feature = "i128", issue = "35118")]
+    #[stable(feature = "i128", since = "1.26.0")]
     fn write_u128(&mut self, i: u128) {
         self.write(&unsafe { mem::transmute::<_, [u8; 16]>(i) })
     }
@@ -348,7 +348,7 @@ pub trait Hasher {
     }
     /// Writes a single `i128` into this hasher.
     #[inline]
-    #[unstable(feature = "i128", issue = "35118")]
+    #[stable(feature = "i128", since = "1.26.0")]
     fn write_i128(&mut self, i: i128) {
         self.write_u128(i as u128)
     }
diff --git a/src/libcore/heap.rs b/src/libcore/heap.rs
new file mode 100644
index 00000000000..fe19c923a58
--- /dev/null
+++ b/src/libcore/heap.rs
@@ -0,0 +1,1075 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![unstable(feature = "allocator_api",
+            reason = "the precise API and guarantees it provides may be tweaked \
+                      slightly, especially to possibly take into account the \
+                      types being stored to make room for a future \
+                      tracing garbage collector",
+            issue = "32838")]
+
+use cmp;
+use fmt;
+use mem;
+use usize;
+use ptr::{self, NonNull};
+
+/// Represents the combination of a starting address and
+/// a total capacity of the returned block.
+#[derive(Debug)]
+pub struct Excess(pub *mut u8, pub usize);
+
+fn size_align<T>() -> (usize, usize) {
+    (mem::size_of::<T>(), mem::align_of::<T>())
+}
+
+/// Layout of a block of memory.
+///
+/// An instance of `Layout` describes a particular layout of memory.
+/// You build a `Layout` up as an input to give to an allocator.
+///
+/// All layouts have an associated non-negative size and a
+/// power-of-two alignment.
+///
+/// (Note however that layouts are *not* required to have positive
+/// size, even though many allocators require that all memory
+/// requests have positive size. A caller to the `Alloc::alloc`
+/// method must either ensure that conditions like this are met, or
+/// use specific allocators with looser requirements.)
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct Layout {
+    // size of the requested block of memory, measured in bytes.
+    size: usize,
+
+    // alignment of the requested block of memory, measured in bytes.
+    // we ensure that this is always a power-of-two, because API's
+    // like `posix_memalign` require it and it is a reasonable
+    // constraint to impose on Layout constructors.
+    //
+    // (However, we do not analogously require `align >= sizeof(void*)`,
+    //  even though that is *also* a requirement of `posix_memalign`.)
+    align: usize,
+}
+
+
+// FIXME: audit default implementations for overflow errors,
+// (potentially switching to overflowing_add and
+//  overflowing_mul as necessary).
+
+impl Layout {
+    /// Constructs a `Layout` from a given `size` and `align`,
+    /// or returns `None` if either of the following conditions
+    /// are not met:
+    ///
+    /// * `align` must be a power of two,
+    ///
+    /// * `size`, when rounded up to the nearest multiple of `align`,
+    ///    must not overflow (i.e. the rounded value must be less than
+    ///    `usize::MAX`).
+    #[inline]
+    pub fn from_size_align(size: usize, align: usize) -> Option<Layout> {
+        if !align.is_power_of_two() {
+            return None;
+        }
+
+        // (power-of-two implies align != 0.)
+
+        // Rounded up size is:
+        //   size_rounded_up = (size + align - 1) & !(align - 1);
+        //
+        // We know from above that align != 0. If adding (align - 1)
+        // does not overflow, then rounding up will be fine.
+        //
+        // Conversely, &-masking with !(align - 1) will subtract off
+        // only low-order-bits. Thus if overflow occurs with the sum,
+        // the &-mask cannot subtract enough to undo that overflow.
+        //
+        // Above implies that checking for summation overflow is both
+        // necessary and sufficient.
+        if size > usize::MAX - (align - 1) {
+            return None;
+        }
+
+        unsafe {
+            Some(Layout::from_size_align_unchecked(size, align))
+        }
+    }
+
+    /// Creates a layout, bypassing all checks.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe as it does not verify that `align` is
+    /// a power-of-two nor `size` aligned to `align` fits within the
+    /// address space (i.e. the `Layout::from_size_align` preconditions).
+    #[inline]
+    pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Layout {
+        Layout { size: size, align: align }
+    }
+
+    /// The minimum size in bytes for a memory block of this layout.
+    #[inline]
+    pub fn size(&self) -> usize { self.size }
+
+    /// The minimum byte alignment for a memory block of this layout.
+    #[inline]
+    pub fn align(&self) -> usize { self.align }
+
+    /// Constructs a `Layout` suitable for holding a value of type `T`.
+    pub fn new<T>() -> Self {
+        let (size, align) = size_align::<T>();
+        Layout::from_size_align(size, align).unwrap()
+    }
+
+    /// Produces layout describing a record that could be used to
+    /// allocate backing structure for `T` (which could be a trait
+    /// or other unsized type like a slice).
+    pub fn for_value<T: ?Sized>(t: &T) -> Self {
+        let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
+        Layout::from_size_align(size, align).unwrap()
+    }
+
+    /// Creates a layout describing the record that can hold a value
+    /// of the same layout as `self`, but that also is aligned to
+    /// alignment `align` (measured in bytes).
+    ///
+    /// If `self` already meets the prescribed alignment, then returns
+    /// `self`.
+    ///
+    /// Note that this method does not add any padding to the overall
+    /// size, regardless of whether the returned layout has a different
+    /// alignment. In other words, if `K` has size 16, `K.align_to(32)`
+    /// will *still* have size 16.
+    ///
+    /// # Panics
+    ///
+    /// Panics if the combination of `self.size` and the given `align`
+    /// violates the conditions listed in `from_size_align`.
+    #[inline]
+    pub fn align_to(&self, align: usize) -> Self {
+        Layout::from_size_align(self.size, cmp::max(self.align, align)).unwrap()
+    }
+
+    /// Returns the amount of padding we must insert after `self`
+    /// to ensure that the following address will satisfy `align`
+    /// (measured in bytes).
+    ///
+    /// E.g. if `self.size` is 9, then `self.padding_needed_for(4)`
+    /// returns 3, because that is the minimum number of bytes of
+    /// padding required to get a 4-aligned address (assuming that the
+    /// corresponding memory block starts at a 4-aligned address).
+    ///
+    /// The return value of this function has no meaning if `align` is
+    /// not a power-of-two.
+    ///
+    /// Note that the utility of the returned value requires `align`
+    /// to be less than or equal to the alignment of the starting
+    /// address for the whole allocated block of memory. One way to
+    /// satisfy this constraint is to ensure `align <= self.align`.
+    #[inline]
+    pub fn padding_needed_for(&self, align: usize) -> usize {
+        let len = self.size();
+
+        // Rounded up value is:
+        //   len_rounded_up = (len + align - 1) & !(align - 1);
+        // and then we return the padding difference: `len_rounded_up - len`.
+        //
+        // We use modular arithmetic throughout:
+        //
+        // 1. align is guaranteed to be > 0, so align - 1 is always
+        //    valid.
+        //
+        // 2. `len + align - 1` can overflow by at most `align - 1`,
+        //    so the &-mask wth `!(align - 1)` will ensure that in the
+        //    case of overflow, `len_rounded_up` will itself be 0.
+        //    Thus the returned padding, when added to `len`, yields 0,
+        //    which trivially satisfies the alignment `align`.
+        //
+        // (Of course, attempts to allocate blocks of memory whose
+        // size and padding overflow in the above manner should cause
+        // the allocator to yield an error anyway.)
+
+        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
+        return len_rounded_up.wrapping_sub(len);
+    }
+
+    /// Creates a layout describing the record for `n` instances of
+    /// `self`, with a suitable amount of padding between each to
+    /// ensure that each instance is given its requested size and
+    /// alignment. On success, returns `(k, offs)` where `k` is the
+    /// layout of the array and `offs` is the distance between the start
+    /// of each element in the array.
+    ///
+    /// On arithmetic overflow, returns `None`.
+    #[inline]
+    pub fn repeat(&self, n: usize) -> Option<(Self, usize)> {
+        let padded_size = self.size.checked_add(self.padding_needed_for(self.align))?;
+        let alloc_size = padded_size.checked_mul(n)?;
+
+        // We can assume that `self.align` is a power-of-two.
+        // Furthermore, `alloc_size` has already been rounded up
+        // to a multiple of `self.align`; therefore, the call to
+        // `Layout::from_size_align` below should never panic.
+        Some((Layout::from_size_align(alloc_size, self.align).unwrap(), padded_size))
+    }
+
+    /// Creates a layout describing the record for `self` followed by
+    /// `next`, including any necessary padding to ensure that `next`
+    /// will be properly aligned. Note that the result layout will
+    /// satisfy the alignment properties of both `self` and `next`.
+    ///
+    /// Returns `Some((k, offset))`, where `k` is layout of the concatenated
+    /// record and `offset` is the relative location, in bytes, of the
+    /// start of the `next` embedded within the concatenated record
+    /// (assuming that the record itself starts at offset 0).
+    ///
+    /// On arithmetic overflow, returns `None`.
+    pub fn extend(&self, next: Self) -> Option<(Self, usize)> {
+        let new_align = cmp::max(self.align, next.align);
+        let realigned = Layout::from_size_align(self.size, new_align)?;
+
+        let pad = realigned.padding_needed_for(next.align);
+
+        let offset = self.size.checked_add(pad)?;
+        let new_size = offset.checked_add(next.size)?;
+
+        let layout = Layout::from_size_align(new_size, new_align)?;
+        Some((layout, offset))
+    }
+
+    /// Creates a layout describing the record for `n` instances of
+    /// `self`, with no padding between each instance.
+    ///
+    /// Note that, unlike `repeat`, `repeat_packed` does not guarantee
+    /// that the repeated instances of `self` will be properly
+    /// aligned, even if a given instance of `self` is properly
+    /// aligned. In other words, if the layout returned by
+    /// `repeat_packed` is used to allocate an array, it is not
+    /// guaranteed that all elements in the array will be properly
+    /// aligned.
+    ///
+    /// On arithmetic overflow, returns `None`.
+    pub fn repeat_packed(&self, n: usize) -> Option<Self> {
+        let size = self.size().checked_mul(n)?;
+        Layout::from_size_align(size, self.align)
+    }
+
+    /// Creates a layout describing the record for `self` followed by
+    /// `next` with no additional padding between the two. Since no
+    /// padding is inserted, the alignment of `next` is irrelevant,
+    /// and is not incorporated *at all* into the resulting layout.
+    ///
+    /// Returns `(k, offset)`, where `k` is layout of the concatenated
+    /// record and `offset` is the relative location, in bytes, of the
+    /// start of the `next` embedded within the concatenated record
+    /// (assuming that the record itself starts at offset 0).
+    ///
+    /// (The `offset` is always the same as `self.size()`; we use this
+    ///  signature out of convenience in matching the signature of
+    ///  `extend`.)
+    ///
+    /// On arithmetic overflow, returns `None`.
+    pub fn extend_packed(&self, next: Self) -> Option<(Self, usize)> {
+        let new_size = self.size().checked_add(next.size())?;
+        let layout = Layout::from_size_align(new_size, self.align)?;
+        Some((layout, self.size()))
+    }
+
+    /// Creates a layout describing the record for a `[T; n]`.
+    ///
+    /// On arithmetic overflow, returns `None`.
+    pub fn array<T>(n: usize) -> Option<Self> {
+        Layout::new::<T>()
+            .repeat(n)
+            .map(|(k, offs)| {
+                debug_assert!(offs == mem::size_of::<T>());
+                k
+            })
+    }
+}
+
+/// The `AllocErr` error specifies whether an allocation failure is
+/// specifically due to resource exhaustion or if it is due to
+/// something wrong when combining the given input arguments with this
+/// allocator.
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub enum AllocErr {
+    /// Error due to hitting some resource limit or otherwise running
+    /// out of memory. This condition strongly implies that *some*
+    /// series of deallocations would allow a subsequent reissuing of
+    /// the original allocation request to succeed.
+    Exhausted { request: Layout },
+
+    /// Error due to allocator being fundamentally incapable of
+    /// satisfying the original request. This condition implies that
+    /// such an allocation request will never succeed on the given
+    /// allocator, regardless of environment, memory pressure, or
+    /// other contextual conditions.
+    ///
+    /// For example, an allocator that does not support requests for
+    /// large memory blocks might return this error variant.
+    Unsupported { details: &'static str },
+}
+
+impl AllocErr {
+    #[inline]
+    pub fn invalid_input(details: &'static str) -> Self {
+        AllocErr::Unsupported { details: details }
+    }
+    #[inline]
+    pub fn is_memory_exhausted(&self) -> bool {
+        if let AllocErr::Exhausted { .. } = *self { true } else { false }
+    }
+    #[inline]
+    pub fn is_request_unsupported(&self) -> bool {
+        if let AllocErr::Unsupported { .. } = *self { true } else { false }
+    }
+    #[inline]
+    pub fn description(&self) -> &str {
+        match *self {
+            AllocErr::Exhausted { .. } => "allocator memory exhausted",
+            AllocErr::Unsupported { .. } => "unsupported allocator request",
+        }
+    }
+}
+
+// (we need this for downstream impl of trait Error)
+impl fmt::Display for AllocErr {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.description())
+    }
+}
+
+/// The `CannotReallocInPlace` error is used when `grow_in_place` or
+/// `shrink_in_place` were unable to reuse the given memory block for
+/// a requested layout.
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct CannotReallocInPlace;
+
+impl CannotReallocInPlace {
+    pub fn description(&self) -> &str {
+        "cannot reallocate allocator's memory in place"
+    }
+}
+
+// (we need this for downstream impl of trait Error)
+impl fmt::Display for CannotReallocInPlace {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.description())
+    }
+}
+
+/// Augments `AllocErr` with a CapacityOverflow variant.
+#[derive(Clone, PartialEq, Eq, Debug)]
+#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
+pub enum CollectionAllocErr {
+    /// Error due to the computed capacity exceeding the collection's maximum
+    /// (usually `isize::MAX` bytes).
+    CapacityOverflow,
+    /// Error due to the allocator (see the `AllocErr` type's docs).
+    AllocErr(AllocErr),
+}
+
+#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
+impl From<AllocErr> for CollectionAllocErr {
+    fn from(err: AllocErr) -> Self {
+        CollectionAllocErr::AllocErr(err)
+    }
+}
+
+/// An implementation of `Alloc` can allocate, reallocate, and
+/// deallocate arbitrary blocks of data described via `Layout`.
+///
+/// Some of the methods require that a memory block be *currently
+/// allocated* via an allocator. This means that:
+///
+/// * the starting address for that memory block was previously
+///   returned by a previous call to an allocation method (`alloc`,
+///   `alloc_zeroed`, `alloc_excess`, `alloc_one`, `alloc_array`) or
+///   reallocation method (`realloc`, `realloc_excess`, or
+///   `realloc_array`), and
+///
+/// * the memory block has not been subsequently deallocated, where
+///   blocks are deallocated either by being passed to a deallocation
+///   method (`dealloc`, `dealloc_one`, `dealloc_array`) or by being
+///   passed to a reallocation method (see above) that returns `Ok`.
+///
+/// A note regarding zero-sized types and zero-sized layouts: many
+/// methods in the `Alloc` trait state that allocation requests
+/// must be non-zero size, or else undefined behavior can result.
+///
+/// * However, some higher-level allocation methods (`alloc_one`,
+///   `alloc_array`) are well-defined on zero-sized types and can
+///   optionally support them: it is left up to the implementor
+///   whether to return `Err`, or to return `Ok` with some pointer.
+///
+/// * If an `Alloc` implementation chooses to return `Ok` in this
+///   case (i.e. the pointer denotes a zero-sized inaccessible block)
+///   then that returned pointer must be considered "currently
+///   allocated". On such an allocator, *all* methods that take
+///   currently-allocated pointers as inputs must accept these
+///   zero-sized pointers, *without* causing undefined behavior.
+///
+/// * In other words, if a zero-sized pointer can flow out of an
+///   allocator, then that allocator must likewise accept that pointer
+///   flowing back into its deallocation and reallocation methods.
+///
+/// Some of the methods require that a layout *fit* a memory block.
+/// What it means for a layout to "fit" a memory block means (or
+/// equivalently, for a memory block to "fit" a layout) is that the
+/// following two conditions must hold:
+///
+/// 1. The block's starting address must be aligned to `layout.align()`.
+///
+/// 2. The block's size must fall in the range `[use_min, use_max]`, where:
+///
+///    * `use_min` is `self.usable_size(layout).0`, and
+///
+///    * `use_max` is the capacity that was (or would have been)
+///      returned when (if) the block was allocated via a call to
+///      `alloc_excess` or `realloc_excess`.
+///
+/// Note that:
+///
+///  * the size of the layout most recently used to allocate the block
+///    is guaranteed to be in the range `[use_min, use_max]`, and
+///
+///  * a lower-bound on `use_max` can be safely approximated by a call to
+///    `usable_size`.
+///
+///  * if a layout `k` fits a memory block (denoted by `ptr`)
+///    currently allocated via an allocator `a`, then it is legal to
+///    use that layout to deallocate it, i.e. `a.dealloc(ptr, k);`.
+///
+/// # Unsafety
+///
+/// The `Alloc` trait is an `unsafe` trait for a number of reasons, and
+/// implementors must ensure that they adhere to these contracts:
+///
+/// * Pointers returned from allocation functions must point to valid memory and
+///   retain their validity until at least the instance of `Alloc` is dropped
+///   itself.
+///
+/// * It's undefined behavior if global allocators unwind.  This restriction may
+///   be lifted in the future, but currently a panic from any of these
+///   functions may lead to memory unsafety. Note that as of the time of this
+///   writing allocators *not* intending to be global allocators can still panic
+///   in their implementation without violating memory safety.
+///
+/// * `Layout` queries and calculations in general must be correct. Callers of
+///   this trait are allowed to rely on the contracts defined on each method,
+///   and implementors must ensure such contracts remain true.
+///
+/// Note that this list may get tweaked over time as clarifications are made in
+/// the future. Additionally global allocators may gain unique requirements for
+/// how to safely implement one in the future as well.
+pub unsafe trait Alloc {
+
+    // (Note: existing allocators have unspecified but well-defined
+    // behavior in response to a zero size allocation request ;
+    // e.g. in C, `malloc` of 0 will either return a null pointer or a
+    // unique pointer, but will not have arbitrary undefined
+    // behavior. Rust should consider revising the alloc::heap crate
+    // to reflect this reality.)
+
+    /// Returns a pointer meeting the size and alignment guarantees of
+    /// `layout`.
+    ///
+    /// If this method returns an `Ok(addr)`, then the `addr` returned
+    /// will be non-null address pointing to a block of storage
+    /// suitable for holding an instance of `layout`.
+    ///
+    /// The returned block of storage may or may not have its contents
+    /// initialized. (Extension subtraits might restrict this
+    /// behavior, e.g. to ensure initialization to particular sets of
+    /// bit patterns.)
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure that `layout` has non-zero size.
+    ///
+    /// (Extension subtraits might provide more specific bounds on
+    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// in response to a zero-size allocation request.)
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `layout` does not meet allocator's size or alignment
+    /// constraints.
+    ///
+    /// Implementations are encouraged to return `Err` on memory
+    /// exhaustion rather than panicking or aborting, but this is not
+    /// a strict requirement. (Specifically: it is *legal* to
+    /// implement this trait atop an underlying native allocation
+    /// library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr>;
+
+    /// Deallocate the memory referenced by `ptr`.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must denote a block of memory currently allocated via
+    ///   this allocator,
+    ///
+    /// * `layout` must *fit* that block of memory,
+    ///
+    /// * In addition to fitting the block of memory `layout`, the
+    ///   alignment of the `layout` must match the alignment used
+    ///   to allocate that block of memory.
+    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout);
+
+    /// Allocator-specific method for signaling an out-of-memory
+    /// condition.
+    ///
+    /// `oom` aborts the thread or process, optionally performing
+    /// cleanup or logging diagnostic information before panicking or
+    /// aborting.
+    ///
+    /// `oom` is meant to be used by clients unable to cope with an
+    /// unsatisfied allocation request (signaled by an error such as
+    /// `AllocErr::Exhausted`), and wish to abandon computation rather
+    /// than attempt to recover locally. Such clients should pass the
+    /// signaling error value back into `oom`, where the allocator
+    /// may incorporate that error value into its diagnostic report
+    /// before aborting.
+    ///
+    /// Implementations of the `oom` method are discouraged from
+    /// infinitely regressing in nested calls to `oom`. In
+    /// practice this means implementors should eschew allocating,
+    /// especially from `self` (directly or indirectly).
+    ///
+    /// Implementations of the allocation and reallocation methods
+    /// (e.g. `alloc`, `alloc_one`, `realloc`) are discouraged from
+    /// panicking (or aborting) in the event of memory exhaustion;
+    /// instead they should return an appropriate error from the
+    /// invoked method, and let the client decide whether to invoke
+    /// this `oom` method in response.
+    fn oom(&mut self, _: AllocErr) -> ! {
+        unsafe { ::intrinsics::abort() }
+    }
+
+    // == ALLOCATOR-SPECIFIC QUANTITIES AND LIMITS ==
+    // usable_size
+
+    /// Returns bounds on the guaranteed usable size of a successful
+    /// allocation created with the specified `layout`.
+    ///
+    /// In particular, if one has a memory block allocated via a given
+    /// allocator `a` and layout `k` where `a.usable_size(k)` returns
+    /// `(l, u)`, then one can pass that block to `a.dealloc()` with a
+    /// layout in the size range [l, u].
+    ///
+    /// (All implementors of `usable_size` must ensure that
+    /// `l <= k.size() <= u`)
+    ///
+    /// Both the lower- and upper-bounds (`l` and `u` respectively)
+    /// are provided, because an allocator based on size classes could
+    /// misbehave if one attempts to deallocate a block without
+    /// providing a correct value for its size (i.e., one within the
+    /// range `[l, u]`).
+    ///
+    /// Clients who wish to make use of excess capacity are encouraged
+    /// to use the `alloc_excess` and `realloc_excess` instead, as
+    /// this method is constrained to report conservative values that
+    /// serve as valid bounds for *all possible* allocation method
+    /// calls.
+    ///
+    /// However, for clients that do not wish to track the capacity
+    /// returned by `alloc_excess` locally, this method is likely to
+    /// produce useful results.
+    #[inline]
+    fn usable_size(&self, layout: &Layout) -> (usize, usize) {
+        (layout.size(), layout.size())
+    }
+
+    // == METHODS FOR MEMORY REUSE ==
+    // realloc. alloc_excess, realloc_excess
+
+    /// Returns a pointer suitable for holding data described by
+    /// `new_layout`, meeting its size and alignment guarantees. To
+    /// accomplish this, this may extend or shrink the allocation
+    /// referenced by `ptr` to fit `new_layout`.
+    ///
+    /// If this returns `Ok`, then ownership of the memory block
+    /// referenced by `ptr` has been transferred to this
+    /// allocator. The memory may or may not have been freed, and
+    /// should be considered unusable (unless of course it was
+    /// transferred back to the caller again via the return value of
+    /// this method).
+    ///
+    /// If this method returns `Err`, then ownership of the memory
+    /// block has not been transferred to this allocator, and the
+    /// contents of the memory block are unaltered.
+    ///
+    /// For best results, `new_layout` should not impose a different
+    /// alignment constraint than `layout`. (In other words,
+    /// `new_layout.align()` should equal `layout.align()`.) However,
+    /// behavior is well-defined (though underspecified) when this
+    /// constraint is violated; further discussion below.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must be currently allocated via this allocator,
+    ///
+    /// * `layout` must *fit* the `ptr` (see above). (The `new_layout`
+    ///   argument need not fit it.)
+    ///
+    /// * `new_layout` must have size greater than zero.
+    ///
+    /// * the alignment of `new_layout` is non-zero.
+    ///
+    /// (Extension subtraits might provide more specific bounds on
+    /// behavior, e.g. guarantee a sentinel address or a null pointer
+    /// in response to a zero-size allocation request.)
+    ///
+    /// # Errors
+    ///
+    /// Returns `Err` only if `new_layout` does not match the
+    /// alignment of `layout`, or does not meet the allocator's size
+    /// and alignment constraints of the allocator, or if reallocation
+    /// otherwise fails.
+    ///
+    /// (Note the previous sentence did not say "if and only if" -- in
+    /// particular, an implementation of this method *can* return `Ok`
+    /// if `new_layout.align() != old_layout.align()`; or it can
+    /// return `Err` in that scenario, depending on whether this
+    /// allocator can dynamically adjust the alignment constraint for
+    /// the block.)
+    ///
+    /// Implementations are encouraged to return `Err` on memory
+    /// exhaustion rather than panicking or aborting, but this is not
+    /// a strict requirement. (Specifically: it is *legal* to
+    /// implement this trait atop an underlying native allocation
+    /// library that aborts on memory exhaustion.)
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// reallocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    unsafe fn realloc(&mut self,
+                      ptr: *mut u8,
+                      layout: Layout,
+                      new_layout: Layout) -> Result<*mut u8, AllocErr> {
+        let new_size = new_layout.size();
+        let old_size = layout.size();
+        let aligns_match = layout.align == new_layout.align;
+
+        if new_size >= old_size && aligns_match {
+            if let Ok(()) = self.grow_in_place(ptr, layout.clone(), new_layout.clone()) {
+                return Ok(ptr);
+            }
+        } else if new_size < old_size && aligns_match {
+            if let Ok(()) = self.shrink_in_place(ptr, layout.clone(), new_layout.clone()) {
+                return Ok(ptr);
+            }
+        }
+
+        // otherwise, fall back on alloc + copy + dealloc.
+        let result = self.alloc(new_layout);
+        if let Ok(new_ptr) = result {
+            ptr::copy_nonoverlapping(ptr as *const u8, new_ptr, cmp::min(old_size, new_size));
+            self.dealloc(ptr, layout);
+        }
+        result
+    }
+
+    /// Behaves like `alloc`, but also ensures that the contents
+    /// are set to zero before being returned.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe for the same reasons that `alloc` is.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `layout` does not meet allocator's size or alignment
+    /// constraints, just as in `alloc`.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
+        let size = layout.size();
+        let p = self.alloc(layout);
+        if let Ok(p) = p {
+            ptr::write_bytes(p, 0, size);
+        }
+        p
+    }
+
+    /// Behaves like `alloc`, but also returns the whole size of
+    /// the returned block. For some `layout` inputs, like arrays, this
+    /// may include extra storage usable for additional data.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe for the same reasons that `alloc` is.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `layout` does not meet allocator's size or alignment
+    /// constraints, just as in `alloc`.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
+        let usable_size = self.usable_size(&layout);
+        self.alloc(layout).map(|p| Excess(p, usable_size.1))
+    }
+
+    /// Behaves like `realloc`, but also returns the whole size of
+    /// the returned block. For some `layout` inputs, like arrays, this
+    /// may include extra storage usable for additional data.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe for the same reasons that `realloc` is.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `layout` does not meet allocator's size or alignment
+    /// constraints, just as in `realloc`.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// reallocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    unsafe fn realloc_excess(&mut self,
+                             ptr: *mut u8,
+                             layout: Layout,
+                             new_layout: Layout) -> Result<Excess, AllocErr> {
+        let usable_size = self.usable_size(&new_layout);
+        self.realloc(ptr, layout, new_layout)
+            .map(|p| Excess(p, usable_size.1))
+    }
+
+    /// Attempts to extend the allocation referenced by `ptr` to fit `new_layout`.
+    ///
+    /// If this returns `Ok`, then the allocator has asserted that the
+    /// memory block referenced by `ptr` now fits `new_layout`, and thus can
+    /// be used to carry data of that layout. (The allocator is allowed to
+    /// expend effort to accomplish this, such as extending the memory block to
+    /// include successor blocks, or virtual memory tricks.)
+    ///
+    /// Regardless of what this method returns, ownership of the
+    /// memory block referenced by `ptr` has not been transferred, and
+    /// the contents of the memory block are unaltered.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must be currently allocated via this allocator,
+    ///
+    /// * `layout` must *fit* the `ptr` (see above); note the
+    ///   `new_layout` argument need not fit it,
+    ///
+    /// * `new_layout.size()` must not be less than `layout.size()`,
+    ///
+    /// * `new_layout.align()` must equal `layout.align()`.
+    ///
+    /// # Errors
+    ///
+    /// Returns `Err(CannotReallocInPlace)` when the allocator is
+    /// unable to assert that the memory block referenced by `ptr`
+    /// could fit `layout`.
+    ///
+    /// Note that one cannot pass `CannotReallocInPlace` to the `oom`
+    /// method; clients are expected either to be able to recover from
+    /// `grow_in_place` failures without aborting, or to fall back on
+    /// another reallocation method before resorting to an abort.
+    unsafe fn grow_in_place(&mut self,
+                            ptr: *mut u8,
+                            layout: Layout,
+                            new_layout: Layout) -> Result<(), CannotReallocInPlace> {
+        let _ = ptr; // this default implementation doesn't care about the actual address.
+        debug_assert!(new_layout.size >= layout.size);
+        debug_assert!(new_layout.align == layout.align);
+        let (_l, u) = self.usable_size(&layout);
+        // _l <= layout.size()                       [guaranteed by usable_size()]
+        //       layout.size() <= new_layout.size()  [required by this method]
+        if new_layout.size <= u {
+            return Ok(());
+        } else {
+            return Err(CannotReallocInPlace);
+        }
+    }
+
+    /// Attempts to shrink the allocation referenced by `ptr` to fit `new_layout`.
+    ///
+    /// If this returns `Ok`, then the allocator has asserted that the
+    /// memory block referenced by `ptr` now fits `new_layout`, and
+    /// thus can only be used to carry data of that smaller
+    /// layout. (The allocator is allowed to take advantage of this,
+    /// carving off portions of the block for reuse elsewhere.) The
+    /// truncated contents of the block within the smaller layout are
+    /// unaltered, and ownership of block has not been transferred.
+    ///
+    /// If this returns `Err`, then the memory block is considered to
+    /// still represent the original (larger) `layout`. None of the
+    /// block has been carved off for reuse elsewhere, ownership of
+    /// the memory block has not been transferred, and the contents of
+    /// the memory block are unaltered.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must be currently allocated via this allocator,
+    ///
+    /// * `layout` must *fit* the `ptr` (see above); note the
+    ///   `new_layout` argument need not fit it,
+    ///
+    /// * `new_layout.size()` must not be greater than `layout.size()`
+    ///   (and must be greater than zero),
+    ///
+    /// * `new_layout.align()` must equal `layout.align()`.
+    ///
+    /// # Errors
+    ///
+    /// Returns `Err(CannotReallocInPlace)` when the allocator is
+    /// unable to assert that the memory block referenced by `ptr`
+    /// could fit `layout`.
+    ///
+    /// Note that one cannot pass `CannotReallocInPlace` to the `oom`
+    /// method; clients are expected either to be able to recover from
+    /// `shrink_in_place` failures without aborting, or to fall back
+    /// on another reallocation method before resorting to an abort.
+    unsafe fn shrink_in_place(&mut self,
+                              ptr: *mut u8,
+                              layout: Layout,
+                              new_layout: Layout) -> Result<(), CannotReallocInPlace> {
+        let _ = ptr; // this default implementation doesn't care about the actual address.
+        debug_assert!(new_layout.size <= layout.size);
+        debug_assert!(new_layout.align == layout.align);
+        let (l, _u) = self.usable_size(&layout);
+        //                      layout.size() <= _u  [guaranteed by usable_size()]
+        // new_layout.size() <= layout.size()        [required by this method]
+        if l <= new_layout.size {
+            return Ok(());
+        } else {
+            return Err(CannotReallocInPlace);
+        }
+    }
+
+
+    // == COMMON USAGE PATTERNS ==
+    // alloc_one, dealloc_one, alloc_array, realloc_array. dealloc_array
+
+    /// Allocates a block suitable for holding an instance of `T`.
+    ///
+    /// Captures a common usage pattern for allocators.
+    ///
+    /// The returned block is suitable for passing to the
+    /// `alloc`/`realloc` methods of this allocator.
+    ///
+    /// Note to implementors: If this returns `Ok(ptr)`, then `ptr`
+    /// must be considered "currently allocated" and must be
+    /// acceptable input to methods such as `realloc` or `dealloc`,
+    /// *even if* `T` is a zero-sized type. In other words, if your
+    /// `Alloc` implementation overrides this method in a manner
+    /// that can return a zero-sized `ptr`, then all reallocation and
+    /// deallocation methods need to be similarly overridden to accept
+    /// such values as input.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `T` does not meet allocator's size or alignment constraints.
+    ///
+    /// For zero-sized `T`, may return either of `Ok` or `Err`, but
+    /// will *not* yield undefined behavior.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr>
+        where Self: Sized
+    {
+        let k = Layout::new::<T>();
+        if k.size() > 0 {
+            unsafe { self.alloc(k).map(|p| NonNull::new_unchecked(p as *mut T)) }
+        } else {
+            Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
+        }
+    }
+
+    /// Deallocates a block suitable for holding an instance of `T`.
+    ///
+    /// The given block must have been produced by this allocator,
+    /// and must be suitable for storing a `T` (in terms of alignment
+    /// as well as minimum and maximum size); otherwise yields
+    /// undefined behavior.
+    ///
+    /// Captures a common usage pattern for allocators.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure both:
+    ///
+    /// * `ptr` must denote a block of memory currently allocated via this allocator
+    ///
+    /// * the layout of `T` must *fit* that block of memory.
+    unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>)
+        where Self: Sized
+    {
+        let raw_ptr = ptr.as_ptr() as *mut u8;
+        let k = Layout::new::<T>();
+        if k.size() > 0 {
+            self.dealloc(raw_ptr, k);
+        }
+    }
+
+    /// Allocates a block suitable for holding `n` instances of `T`.
+    ///
+    /// Captures a common usage pattern for allocators.
+    ///
+    /// The returned block is suitable for passing to the
+    /// `alloc`/`realloc` methods of this allocator.
+    ///
+    /// Note to implementors: If this returns `Ok(ptr)`, then `ptr`
+    /// must be considered "currently allocated" and must be
+    /// acceptable input to methods such as `realloc` or `dealloc`,
+    /// *even if* `T` is a zero-sized type. In other words, if your
+    /// `Alloc` implementation overrides this method in a manner
+    /// that can return a zero-sized `ptr`, then all reallocation and
+    /// deallocation methods need to be similarly overridden to accept
+    /// such values as input.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `[T; n]` does not meet allocator's size or alignment
+    /// constraints.
+    ///
+    /// For zero-sized `T` or `n == 0`, may return either of `Ok` or
+    /// `Err`, but will *not* yield undefined behavior.
+    ///
+    /// Always returns `Err` on arithmetic overflow.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// allocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr>
+        where Self: Sized
+    {
+        match Layout::array::<T>(n) {
+            Some(ref layout) if layout.size() > 0 => {
+                unsafe {
+                    self.alloc(layout.clone())
+                        .map(|p| {
+                            NonNull::new_unchecked(p as *mut T)
+                        })
+                }
+            }
+            _ => Err(AllocErr::invalid_input("invalid layout for alloc_array")),
+        }
+    }
+
+    /// Reallocates a block previously suitable for holding `n_old`
+    /// instances of `T`, returning a block suitable for holding
+    /// `n_new` instances of `T`.
+    ///
+    /// Captures a common usage pattern for allocators.
+    ///
+    /// The returned block is suitable for passing to the
+    /// `alloc`/`realloc` methods of this allocator.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure all of the following:
+    ///
+    /// * `ptr` must be currently allocated via this allocator,
+    ///
+    /// * the layout of `[T; n_old]` must *fit* that block of memory.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either memory is exhausted or
+    /// `[T; n_new]` does not meet allocator's size or alignment
+    /// constraints.
+    ///
+    /// For zero-sized `T` or `n_new == 0`, may return either of `Ok` or
+    /// `Err`, but will *not* yield undefined behavior.
+    ///
+    /// Always returns `Err` on arithmetic overflow.
+    ///
+    /// Clients wishing to abort computation in response to an
+    /// reallocation error are encouraged to call the allocator's `oom`
+    /// method, rather than directly invoking `panic!` or similar.
+    unsafe fn realloc_array<T>(&mut self,
+                               ptr: NonNull<T>,
+                               n_old: usize,
+                               n_new: usize) -> Result<NonNull<T>, AllocErr>
+        where Self: Sized
+    {
+        match (Layout::array::<T>(n_old), Layout::array::<T>(n_new), ptr.as_ptr()) {
+            (Some(ref k_old), Some(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => {
+                self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone())
+                    .map(|p| NonNull::new_unchecked(p as *mut T))
+            }
+            _ => {
+                Err(AllocErr::invalid_input("invalid layout for realloc_array"))
+            }
+        }
+    }
+
+    /// Deallocates a block suitable for holding `n` instances of `T`.
+    ///
+    /// Captures a common usage pattern for allocators.
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because undefined behavior can result
+    /// if the caller does not ensure both:
+    ///
+    /// * `ptr` must denote a block of memory currently allocated via this allocator
+    ///
+    /// * the layout of `[T; n]` must *fit* that block of memory.
+    ///
+    /// # Errors
+    ///
+    /// Returning `Err` indicates that either `[T; n]` or the given
+    /// memory block does not meet allocator's size or alignment
+    /// constraints.
+    ///
+    /// Always returns `Err` on arithmetic overflow.
+    unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), AllocErr>
+        where Self: Sized
+    {
+        let raw_ptr = ptr.as_ptr() as *mut u8;
+        match Layout::array::<T>(n) {
+            Some(ref k) if k.size() > 0 => {
+                Ok(self.dealloc(raw_ptr, k.clone()))
+            }
+            _ => {
+                Err(AllocErr::invalid_input("invalid layout for dealloc_array"))
+            }
+        }
+    }
+}
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 830ebad0654..3b740adc468 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1314,6 +1314,11 @@ extern "rust-intrinsic" {
     /// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
     pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);
 
+    /// Performs an exact division, resulting in undefined behavior where
+    /// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`
+    #[cfg(not(stage0))]
+    pub fn exact_div<T>(x: T, y: T) -> T;
+
     /// Performs an unchecked division, resulting in undefined behavior
     /// where y = 0 or x = `T::min_value()` and y = -1
     pub fn unchecked_div<T>(x: T, y: T) -> T;
@@ -1396,3 +1401,8 @@ extern "rust-intrinsic" {
     /// Probably will never become stable.
     pub fn nontemporal_store<T>(ptr: *mut T, val: T);
 }
+
+#[cfg(stage0)]
+pub unsafe fn exact_div<T>(a: T, b: T) -> T {
+    unchecked_div(a, b)
+}
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index 2cfbc092293..4ccf446aa63 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -974,13 +974,13 @@ pub trait Iterator {
     ///     // each iteration, we'll multiply the state by the element
     ///     *state = *state * x;
     ///
-    ///     // the value passed on to the next iteration
-    ///     Some(*state)
+    ///     // then, we'll yield the negation of the state
+    ///     Some(-*state)
     /// });
     ///
-    /// assert_eq!(iter.next(), Some(1));
-    /// assert_eq!(iter.next(), Some(2));
-    /// assert_eq!(iter.next(), Some(6));
+    /// assert_eq!(iter.next(), Some(-1));
+    /// assert_eq!(iter.next(), Some(-2));
+    /// assert_eq!(iter.next(), Some(-6));
     /// assert_eq!(iter.next(), None);
     /// ```
     #[inline]
@@ -1368,6 +1368,7 @@ pub trait Iterator {
     /// [`Result`]: ../../std/result/enum.Result.html
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"]
     fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
         FromIterator::from_iter(self)
     }
@@ -1446,7 +1447,6 @@ pub trait Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = [1, 2, 3];
     ///
     /// // the checked sum of all of the elements of the array
@@ -1458,7 +1458,6 @@ pub trait Iterator {
     /// Short-circuiting:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = [10, 20, 30, 100, 40, 50];
     /// let mut it = a.iter();
     ///
@@ -1472,7 +1471,7 @@ pub trait Iterator {
     /// assert_eq!(it.next(), Some(&40));
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     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>
     {
@@ -1495,7 +1494,6 @@ pub trait Iterator {
     /// # Examples
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// use std::fs::rename;
     /// use std::io::{stdout, Write};
     /// use std::path::Path;
@@ -1512,7 +1510,7 @@ pub trait Iterator {
     /// assert_eq!(it.next(), Some("stale_bread.json"));
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     fn try_for_each<F, R>(&mut self, mut f: F) -> R where
         Self: Sized, F: FnMut(Self::Item) -> R, R: Try<Ok=()>
     {
@@ -1745,6 +1743,38 @@ pub trait Iterator {
         }).break_value()
     }
 
+    /// Applies function to the elements of iterator and returns
+    /// the first non-none result.
+    ///
+    /// `iter.find_map(f)` is equivalent to `iter.filter_map(f).next()`.
+    ///
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(iterator_find_map)]
+    /// let a = ["lol", "NaN", "2", "5"];
+    ///
+    /// let mut first_number = a.iter().find_map(|s| s.parse().ok());
+    ///
+    /// assert_eq!(first_number, Some(2));
+    /// ```
+    #[inline]
+    #[unstable(feature = "iterator_find_map",
+               reason = "unstable new API",
+               issue = "49602")]
+    fn find_map<B, F>(&mut self, mut f: F) -> Option<B> where
+        Self: Sized,
+        F: FnMut(Self::Item) -> Option<B>,
+    {
+        self.try_for_each(move |x| {
+            match f(x) {
+                Some(x) => LoopState::Break(x),
+                None => LoopState::Continue(()),
+            }
+        }).break_value()
+    }
+
     /// Searches for an element in an iterator, returning its index.
     ///
     /// `position()` takes a closure that returns `true` or `false`. It applies
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index b1b783b47c7..1e8476d3880 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -1872,7 +1872,7 @@ impl<I: Iterator> Iterator for Peekable<I> {
 
     #[inline]
     fn nth(&mut self, n: usize) -> Option<I::Item> {
-        // FIXME(#6393): merge these when borrow-checking gets better.
+        // FIXME(#43234): merge these when borrow-checking gets better.
         if n == 0 {
             match self.peeked.take() {
                 Some(v) => v,
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs
index 8d1080bb876..5d57207763e 100644
--- a/src/libcore/iter/range.rs
+++ b/src/libcore/iter/range.rs
@@ -91,7 +91,7 @@ macro_rules! step_impl_unsigned {
             #[inline]
             #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
-                match <$t>::try_from(n) {
+                match <$t>::private_try_from(n) {
                     Ok(n_as_t) => self.checked_add(n_as_t),
                     Err(_) => None,
                 }
@@ -123,7 +123,7 @@ macro_rules! step_impl_signed {
             #[inline]
             #[allow(unreachable_patterns)]
             fn add_usize(&self, n: usize) -> Option<Self> {
-                match <$unsigned>::try_from(n) {
+                match <$unsigned>::private_try_from(n) {
                     Ok(n_as_unsigned) => {
                         // Wrapping in unsigned space handles cases like
                         // `-120_i8.add_usize(200) == Some(80_i8)`,
@@ -461,3 +461,74 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
 
 #[stable(feature = "fused", since = "1.26.0")]
 impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
+
+/// Compensate removal of some impls per
+/// https://github.com/rust-lang/rust/pull/49305#issuecomment-376293243
+trait PrivateTryFromUsize: Sized {
+    fn private_try_from(n: usize) -> Result<Self, ()>;
+}
+
+impl<T> PrivateTryFromUsize for T where T: TryFrom<usize> {
+    #[inline]
+    fn private_try_from(n: usize) -> Result<Self, ()> {
+        T::try_from(n).map_err(|_| ())
+    }
+}
+
+// no possible bounds violation
+macro_rules! try_from_unbounded {
+    ($($target:ty),*) => {$(
+        impl PrivateTryFromUsize for $target {
+            #[inline]
+            fn private_try_from(value: usize) -> Result<Self, ()> {
+                Ok(value as $target)
+            }
+        }
+    )*}
+}
+
+// unsigned to signed (only positive bound)
+#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
+macro_rules! try_from_upper_bounded {
+    ($($target:ty),*) => {$(
+        impl PrivateTryFromUsize for $target {
+            #[inline]
+            fn private_try_from(u: usize) -> Result<$target, ()> {
+                if u > (<$target>::max_value() as usize) {
+                    Err(())
+                } else {
+                    Ok(u as $target)
+                }
+            }
+        }
+    )*}
+}
+
+
+#[cfg(target_pointer_width = "16")]
+mod ptr_try_from_impls {
+    use super::PrivateTryFromUsize;
+
+    try_from_unbounded!(u16, u32, u64, u128);
+    try_from_unbounded!(i32, i64, i128);
+}
+
+#[cfg(target_pointer_width = "32")]
+mod ptr_try_from_impls {
+    use super::PrivateTryFromUsize;
+
+    try_from_upper_bounded!(u16);
+    try_from_unbounded!(u32, u64, u128);
+    try_from_upper_bounded!(i32);
+    try_from_unbounded!(i64, i128);
+}
+
+#[cfg(target_pointer_width = "64")]
+mod ptr_try_from_impls {
+    use super::PrivateTryFromUsize;
+
+    try_from_upper_bounded!(u16, u32);
+    try_from_unbounded!(u64, u128);
+    try_from_upper_bounded!(i32, i64);
+    try_from_unbounded!(i128);
+}
diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs
index 0267fcd3754..ddbb5998942 100644
--- a/src/libcore/iter/traits.rs
+++ b/src/libcore/iter/traits.rs
@@ -427,7 +427,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = ["1", "2", "3"];
     /// let sum = a.iter()
     ///     .map(|&s| s.parse::<i32>())
@@ -438,7 +437,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Short-circuiting:
     ///
     /// ```
-    /// #![feature(iterator_try_fold)]
     /// let a = ["1", "rust", "3"];
     /// let mut it = a.iter();
     /// let sum = it
@@ -452,7 +450,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// assert_eq!(it.next_back(), Some(&"1"));
     /// ```
     #[inline]
-    #[unstable(feature = "iterator_try_fold", issue = "45594")]
+    #[stable(feature = "iterator_try_fold", since = "1.27.0")]
     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>
     {
@@ -491,7 +489,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_rfold)]
     /// let a = [1, 2, 3];
     ///
     /// // the sum of all of the elements of a
@@ -505,7 +502,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// and continuing with each element from the back until the front:
     ///
     /// ```
-    /// #![feature(iter_rfold)]
     /// let numbers = [1, 2, 3, 4, 5];
     ///
     /// let zero = "0".to_string();
@@ -517,14 +513,14 @@ pub trait DoubleEndedIterator: Iterator {
     /// assert_eq!(result, "(1 + (2 + (3 + (4 + (5 + 0)))))");
     /// ```
     #[inline]
-    #[unstable(feature = "iter_rfold", issue = "44705")]
+    #[stable(feature = "iter_rfold", since = "1.27.0")]
     fn rfold<B, F>(mut self, accum: B, mut f: F) -> B where
         Self: Sized, F: FnMut(B, Self::Item) -> B,
     {
         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.
+    /// Searches for an element of an iterator from the back that satisfies a predicate.
     ///
     /// `rfind()` takes a closure that returns `true` or `false`. It applies
     /// this closure to each element of the iterator, starting at the end, and if any
@@ -547,8 +543,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Basic usage:
     ///
     /// ```
-    /// #![feature(iter_rfind)]
-    ///
     /// let a = [1, 2, 3];
     ///
     /// assert_eq!(a.iter().rfind(|&&x| x == 2), Some(&2));
@@ -559,8 +553,6 @@ pub trait DoubleEndedIterator: Iterator {
     /// Stopping at the first `true`:
     ///
     /// ```
-    /// #![feature(iter_rfind)]
-    ///
     /// let a = [1, 2, 3];
     ///
     /// let mut iter = a.iter();
@@ -571,7 +563,7 @@ pub trait DoubleEndedIterator: Iterator {
     /// assert_eq!(iter.next_back(), Some(&1));
     /// ```
     #[inline]
-    #[unstable(feature = "iter_rfind", issue = "39480")]
+    #[stable(feature = "iter_rfind", since = "1.27.0")]
     fn rfind<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
         Self: Sized,
         P: FnMut(&Self::Item) -> bool
@@ -901,6 +893,15 @@ impl<I, T, E> Iterator for ResultShunt<I, E>
             None => None,
         }
     }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        if self.error.is_some() {
+            (0, Some(0))
+        } else {
+            let (_, upper) = self.iter.size_hint();
+            (0, upper)
+        }
+    }
 }
 
 #[stable(feature = "iter_arith_traits_result", since="1.16.0")]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 9aebe2e4ee4..5a62b8438f9 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -78,7 +78,7 @@
 #![feature(doc_spotlight)]
 #![feature(fn_must_use)]
 #![feature(fundamental)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
 #![feature(intrinsics)]
 #![feature(iterator_flatten)]
@@ -86,6 +86,7 @@
 #![feature(lang_items)]
 #![feature(link_llvm_intrinsics)]
 #![feature(exhaustive_patterns)]
+#![feature(macro_at_most_once_rep)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]
 #![feature(optin_builtin_traits)]
@@ -185,6 +186,10 @@ pub mod hash;
 pub mod fmt;
 pub mod time;
 
+/* Heap memory allocator trait */
+#[allow(missing_docs)]
+pub mod heap;
+
 // note: does not need to be public
 mod char_private;
 mod iter_private;
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index f8a33961811..885aabe0806 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -260,6 +260,21 @@ pub trait Unsize<T: ?Sized> {
 /// non-`Copy` in the future, it could be prudent to omit the `Copy` implementation now, to
 /// avoid a breaking API change.
 ///
+/// ## Additional implementors
+///
+/// In addition to the [implementors listed below][impls],
+/// the following types also implement `Copy`:
+///
+/// * Function item types (i.e. the distinct types defined for each function)
+/// * Function pointer types (e.g. `fn() -> i32`)
+/// * Array types, for all sizes, if the item type also implements `Copy` (e.g. `[i32; 123456]`)
+/// * Tuple types, if each component also implements `Copy` (e.g. `()`, `(i32, bool)`)
+/// * Closure types, if they capture no value from the environment
+///   or if all such captured values implement `Copy` themselves.
+///   Note that variables captured by shared reference always implement `Copy`
+///   (even if the referent doesn't),
+///   while variables captured by mutable reference never implement `Copy`.
+///
 /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`Drop`]: ../../std/ops/trait.Drop.html
@@ -267,6 +282,7 @@ pub trait Unsize<T: ?Sized> {
 /// [`Clone`]: ../clone/trait.Clone.html
 /// [`String`]: ../../std/string/struct.String.html
 /// [`i32`]: ../../std/primitive.i32.html
+/// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "copy"]
 pub trait Copy : Clone {
@@ -588,3 +604,43 @@ unsafe impl<'a, T: ?Sized> Freeze for &'a mut T {}
 /// This trait is automatically implemented for almost every type.
 #[unstable(feature = "pin", issue = "49150")]
 pub unsafe auto trait Unpin {}
+
+/// Implementations of `Copy` for primitive types.
+///
+/// Implementations that cannot be described in Rust
+/// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
+#[cfg(not(stage0))]
+mod copy_impls {
+
+    use super::Copy;
+
+    macro_rules! impl_copy {
+        ($($t:ty)*) => {
+            $(
+                #[stable(feature = "rust1", since = "1.0.0")]
+                impl Copy for $t {}
+            )*
+        }
+    }
+
+    impl_copy! {
+        usize u8 u16 u32 u64 u128
+        isize i8 i16 i32 i64 i128
+        f32 f64
+        bool char
+    }
+
+    #[stable(feature = "never_type", since = "1.26.0")]
+    impl Copy for ! {}
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Copy for *const T {}
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<T: ?Sized> Copy for *mut T {}
+
+    // Shared references can be copied, but mutable references *cannot*!
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<'a, T: ?Sized> Copy for &'a T {}
+
+}
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs
index 2c966eb3b57..19836d98844 100644
--- a/src/libcore/nonzero.rs
+++ b/src/libcore/nonzero.rs
@@ -9,9 +9,10 @@
 // except according to those terms.
 
 //! Exposes the NonZero lang item which provides optimization hints.
-#![unstable(feature = "nonzero",
-            reason = "needs an RFC to flesh out the design",
-            issue = "27730")]
+#![unstable(feature = "nonzero", reason = "deprecated", issue = "49137")]
+#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead",
+                    since = "1.26.0")]
+#![allow(deprecated)]
 
 use ops::CoerceUnsized;
 
@@ -62,14 +63,11 @@ impl_zeroable_for_integer_types! {
 /// NULL or 0 that might allow certain optimizations.
 #[lang = "non_zero"]
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
-pub struct NonZero<T: Zeroable>(T);
+pub struct NonZero<T: Zeroable>(pub(crate) T);
 
 impl<T: Zeroable> NonZero<T> {
     /// Creates an instance of NonZero with the provided value.
     /// You must indeed ensure that the value is actually "non-zero".
-    #[unstable(feature = "nonzero",
-               reason = "needs an RFC to flesh out the design",
-               issue = "27730")]
     #[inline]
     pub const unsafe fn new_unchecked(inner: T) -> Self {
         NonZero(inner)
diff --git a/src/libcore/num/i128.rs b/src/libcore/num/i128.rs
index 04354e2e33f..989376d1ac2 100644
--- a/src/libcore/num/i128.rs
+++ b/src/libcore/num/i128.rs
@@ -12,6 +12,6 @@
 //!
 //! *[See also the `i128` primitive type](../../std/primitive.i128.html).*
 
-#![unstable(feature = "i128", issue="35118")]
+#![stable(feature = "i128", since = "1.26.0")]
 
-int_module! { i128, #[unstable(feature = "i128", issue="35118")] }
+int_module! { i128, #[stable(feature = "i128", since="1.26.0")] }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 09ab7060d37..dcda404721c 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -12,12 +12,111 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use convert::{Infallible, TryFrom};
+use convert::TryFrom;
 use fmt;
 use intrinsics;
+#[allow(deprecated)] use nonzero::NonZero;
 use ops;
 use str::FromStr;
 
+macro_rules! impl_nonzero_fmt {
+    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
+        $(
+            #[$stability]
+            #[allow(deprecated)]
+            impl fmt::$Trait for $Ty {
+                #[inline]
+                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+                    self.get().fmt(f)
+                }
+            }
+        )+
+    }
+}
+
+macro_rules! nonzero_integers {
+    ( #[$stability: meta] #[$deprecation: meta] $( $Ty: ident($Int: ty); )+ ) => {
+        $(
+            /// An integer that is known not to equal zero.
+            ///
+            /// This may enable some memory layout optimization such as:
+            ///
+            /// ```rust
+            /// # #![feature(nonzero)]
+            /// use std::mem::size_of;
+            /// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
+            /// ```
+            #[$stability]
+            #[$deprecation]
+            #[allow(deprecated)]
+            #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+            pub struct $Ty(NonZero<$Int>);
+
+            #[allow(deprecated)]
+            impl $Ty {
+                /// Create a non-zero without checking the value.
+                ///
+                /// # Safety
+                ///
+                /// The value must not be zero.
+                #[$stability]
+                #[inline]
+                pub const unsafe fn new_unchecked(n: $Int) -> Self {
+                    $Ty(NonZero(n))
+                }
+
+                /// Create a non-zero if the given value is not zero.
+                #[$stability]
+                #[inline]
+                pub fn new(n: $Int) -> Option<Self> {
+                    if n != 0 {
+                        Some($Ty(NonZero(n)))
+                    } else {
+                        None
+                    }
+                }
+
+                /// Returns the value as a primitive type.
+                #[$stability]
+                #[inline]
+                pub fn get(self) -> $Int {
+                    self.0 .0
+                }
+
+            }
+
+            impl_nonzero_fmt! {
+                #[$stability]
+                (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
+            }
+        )+
+    }
+}
+
+nonzero_integers! {
+    #[unstable(feature = "nonzero", issue = "49137")]
+    #[allow(deprecated)]  // Redundant, works around "error: inconsistent lockstep iteration"
+    NonZeroU8(u8);
+    NonZeroU16(u16);
+    NonZeroU32(u32);
+    NonZeroU64(u64);
+    NonZeroU128(u128);
+    NonZeroUsize(usize);
+}
+
+nonzero_integers! {
+    #[unstable(feature = "nonzero", issue = "49137")]
+    #[rustc_deprecated(since = "1.26.0", reason = "\
+        signed non-zero integers are considered for removal due to lack of known use cases. \
+        If you’re using them, please comment on https://github.com/rust-lang/rust/issues/49137")]
+    NonZeroI8(i8);
+    NonZeroI16(i16);
+    NonZeroI32(i32);
+    NonZeroI64(i64);
+    NonZeroI128(i128);
+    NonZeroIsize(isize);
+}
+
 /// Provides intentionally-wrapped arithmetic on `T`.
 ///
 /// Operations like `+` on `u32` values is intended to never overflow,
@@ -1546,11 +1645,7 @@ impl i64 {
 #[lang = "i128"]
 impl i128 {
     int_impl! { i128, i128, u128, 128, -170141183460469231731687303715884105728,
-        170141183460469231731687303715884105727, "#![feature(i128_type)]
-#![feature(i128)]
-# fn main() {
-", "
-# }" }
+        170141183460469231731687303715884105727, "", "" }
 }
 
 #[cfg(target_pointer_width = "16")]
@@ -3404,12 +3499,7 @@ impl u64 {
 
 #[lang = "u128"]
 impl u128 {
-    uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "#![feature(i128_type)]
-#![feature(i128)]
-
-# fn main() {
-", "
-# }" }
+    uint_impl! { u128, u128, 128, 340282366920938463463374607431768211455, "", "" }
 }
 
 #[cfg(target_pointer_width = "16")]
@@ -3573,7 +3663,7 @@ macro_rules! from_str_radix_int_impl {
 from_str_radix_int_impl! { isize i8 i16 i32 i64 i128 usize u8 u16 u32 u64 u128 }
 
 /// The error type returned when a checked integral type conversion fails.
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromIntError(());
 
@@ -3588,40 +3678,24 @@ impl TryFromIntError {
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
+#[stable(feature = "try_from", since = "1.26.0")]
 impl fmt::Display for TryFromIntError {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         self.__description().fmt(fmt)
     }
 }
 
-#[unstable(feature = "try_from", issue = "33417")]
-impl From<Infallible> for TryFromIntError {
-    fn from(infallible: Infallible) -> TryFromIntError {
-        match infallible {
-        }
+#[stable(feature = "try_from", since = "1.26.0")]
+impl From<!> for TryFromIntError {
+    fn from(never: !) -> TryFromIntError {
+        never
     }
 }
 
-// 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 = Infallible;
-
-            #[inline]
-            fn try_from(value: $source) -> Result<Self, Self::Error> {
-                Ok(value as $target)
-            }
-        }
-    )*}
-}
-
 // only negative bounds
 macro_rules! try_from_lower_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
+        #[stable(feature = "try_from", since = "1.26.0")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -3640,7 +3714,7 @@ macro_rules! try_from_lower_bounded {
 // unsigned to signed (only positive bound)
 macro_rules! try_from_upper_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
+        #[stable(feature = "try_from", since = "1.26.0")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -3659,7 +3733,7 @@ macro_rules! try_from_upper_bounded {
 // all other cases
 macro_rules! try_from_both_bounded {
     ($source:ty, $($target:ty),*) => {$(
-        #[unstable(feature = "try_from", issue = "33417")]
+        #[stable(feature = "try_from", since = "1.26.0")]
         impl TryFrom<$source> for $target {
             type Error = TryFromIntError;
 
@@ -3716,82 +3790,44 @@ try_from_both_bounded!(i128, u64, u32, u16, u8);
 try_from_upper_bounded!(usize, isize);
 try_from_lower_bounded!(isize, usize);
 
+try_from_upper_bounded!(usize, u8);
+try_from_upper_bounded!(usize, i8, i16);
+try_from_both_bounded!(isize, u8);
+try_from_both_bounded!(isize, i8);
+
 #[cfg(target_pointer_width = "16")]
 mod ptr_try_from_impls {
     use super::TryFromIntError;
-    use convert::{Infallible, TryFrom};
-
-    try_from_upper_bounded!(usize, u8);
-    try_from_unbounded!(usize, u16, u32, u64, u128);
-    try_from_upper_bounded!(usize, i8, i16);
-    try_from_unbounded!(usize, i32, i64, i128);
+    use convert::TryFrom;
 
-    try_from_both_bounded!(isize, u8);
+    // Fallible across platfoms, only implementation differs
     try_from_lower_bounded!(isize, u16, u32, u64, u128);
-    try_from_both_bounded!(isize, i8);
-    try_from_unbounded!(isize, i16, i32, i64, i128);
-
-    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, 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::{Infallible, TryFrom};
-
-    try_from_upper_bounded!(usize, u8, u16);
-    try_from_unbounded!(usize, u32, u64, u128);
-    try_from_upper_bounded!(usize, i8, i16, i32);
-    try_from_unbounded!(usize, i64, i128);
+    use convert::TryFrom;
 
-    try_from_both_bounded!(isize, u8, u16);
+    // Fallible across platfoms, only implementation differs
+    try_from_both_bounded!(isize, u16);
     try_from_lower_bounded!(isize, u32, u64, u128);
-    try_from_both_bounded!(isize, i8, i16);
-    try_from_unbounded!(isize, i32, i64, i128);
-
-    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, 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::{Infallible, TryFrom};
-
-    try_from_upper_bounded!(usize, u8, u16, u32);
-    try_from_unbounded!(usize, u64, u128);
-    try_from_upper_bounded!(usize, i8, i16, i32, i64);
-    try_from_unbounded!(usize, i128);
+    use convert::TryFrom;
 
-    try_from_both_bounded!(isize, u8, u16, u32);
+    // Fallible across platfoms, only implementation differs
+    try_from_both_bounded!(isize, u16, u32);
     try_from_lower_bounded!(isize, u64, u128);
-    try_from_both_bounded!(isize, i8, i16, i32);
-    try_from_unbounded!(isize, i64, i128);
-
-    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, i16, i32, i64);
-    rev!(try_from_both_bounded, isize, i128);
 }
 
 #[doc(hidden)]
@@ -3967,39 +4003,53 @@ macro_rules! impl_from {
 impl_from! { u8, u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u8, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u8, u128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u8, usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u16, u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u16, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u16, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u16, u128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u32, u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u32, u128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { u64, u128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u32, u128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { u64, u128, #[stable(feature = "i128", since = "1.26.0")] }
 
 // Signed -> Signed
 impl_from! { i8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i8, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i8, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { i8, isize, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { i16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i16, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i16, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { i32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { i32, i128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { i64, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { i32, i128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { i64, i128, #[stable(feature = "i128", since = "1.26.0")] }
 
 // Unsigned -> Signed
 impl_from! { u8, i16, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u8, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u8, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u8, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u16, i32, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
 impl_from! { u16, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u16, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u16, i128, #[stable(feature = "i128", since = "1.26.0")] }
 impl_from! { u32, i64, #[stable(feature = "lossless_int_conv", since = "1.5.0")] }
-impl_from! { u32, i128, #[unstable(feature = "i128", issue = "35118")] }
-impl_from! { u64, i128, #[unstable(feature = "i128", issue = "35118")] }
+impl_from! { u32, i128, #[stable(feature = "i128", since = "1.26.0")] }
+impl_from! { u64, i128, #[stable(feature = "i128", since = "1.26.0")] }
+
+// The C99 standard defines bounds on INTPTR_MIN, INTPTR_MAX, and UINTPTR_MAX
+// which imply that pointer-sized integers must be at least 16 bits:
+// https://port70.net/~nsz/c/c99/n1256.html#7.18.2.4
+impl_from! { u16, usize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+impl_from! { u8, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+impl_from! { i16, isize, #[stable(feature = "lossless_iusize_conv", since = "1.26.0")] }
+
+// RISC-V defines the possibility of a 128-bit address space (RV128).
+
+// CHERI proposes 256-bit “capabilities”. Unclear if this would be relevant to usize/isize.
+// https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/20171017a-cheri-poster.pdf
+// http://www.csl.sri.com/users/neumann/2012resolve-cheri.pdf
+
 
 // Note: integers can only be represented with full precision in a float if
 // they fit in the significand, which is 24 bits in f32 and 53 bits in f64.
diff --git a/src/libcore/num/u128.rs b/src/libcore/num/u128.rs
index 987ac3e0007..e8c783a1bb5 100644
--- a/src/libcore/num/u128.rs
+++ b/src/libcore/num/u128.rs
@@ -12,5 +12,5 @@
 //!
 //! *[See also the `u128` primitive type](../../std/primitive.u128.html).*
 
-#![unstable(feature = "i128", issue="35118")]
-uint_module! { u128, #[unstable(feature = "i128", issue="35118")] }
+#![stable(feature = "i128", since = "1.26.0")]
+uint_module! { u128, #[stable(feature = "i128", since="1.26.0")] }
diff --git a/src/libcore/ops/drop.rs b/src/libcore/ops/drop.rs
index 70ab7b2f3b7..474f7e34c34 100644
--- a/src/libcore/ops/drop.rs
+++ b/src/libcore/ops/drop.rs
@@ -95,7 +95,7 @@
 pub trait Drop {
     /// Executes the destructor for this type.
     ///
-    /// This method is called implilcitly when the value goes out of scope,
+    /// This method is called implicitly when the value goes out of scope,
     /// and cannot be called explicitly (this is compiler error [E0040]).
     /// However, the [`std::mem::drop`] function in the prelude can be
     /// used to call the argument's `Drop` implementation.
diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs
index dc7669d195c..4b70c5398be 100644
--- a/src/libcore/ops/generator.rs
+++ b/src/libcore/ops/generator.rs
@@ -56,11 +56,11 @@ pub enum GeneratorState<Y, R> {
 ///         return "foo"
 ///     };
 ///
-///     match generator.resume() {
+///     match unsafe { generator.resume() } {
 ///         GeneratorState::Yielded(1) => {}
 ///         _ => panic!("unexpected return from resume"),
 ///     }
-///     match generator.resume() {
+///     match unsafe { generator.resume() } {
 ///         GeneratorState::Complete("foo") => {}
 ///         _ => panic!("unexpected return from resume"),
 ///     }
@@ -98,6 +98,10 @@ pub trait Generator {
     /// generator will continue executing until it either yields or returns, at
     /// which point this function will return.
     ///
+    /// The function is unsafe because it can be used on an immovable generator.
+    /// After such a call, the immovable generator must not move again, but
+    /// this is not enforced by the compiler.
+    ///
     /// # Return value
     ///
     /// The `GeneratorState` enum returned from this function indicates what
@@ -116,7 +120,7 @@ pub trait Generator {
     /// been returned previously. While generator literals in the language are
     /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
     /// for all implementations of the `Generator` trait.
-    fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
+    unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return>;
 }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
@@ -125,7 +129,7 @@ impl<'a, T> Generator for &'a mut T
 {
     type Yield = T::Yield;
     type Return = T::Return;
-    fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
+    unsafe fn resume(&mut self) -> GeneratorState<Self::Yield, Self::Return> {
         (**self).resume()
     }
 }
diff --git a/src/libcore/ops/mod.rs b/src/libcore/ops/mod.rs
index 234970a81fa..ce4f45762de 100644
--- a/src/libcore/ops/mod.rs
+++ b/src/libcore/ops/mod.rs
@@ -161,7 +161,6 @@ mod drop;
 mod function;
 mod generator;
 mod index;
-mod place;
 mod range;
 mod try;
 mod unsize;
@@ -192,7 +191,7 @@ pub use self::index::{Index, IndexMut};
 pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
 
 #[stable(feature = "inclusive_range", since = "1.26.0")]
-pub use self::range::{RangeInclusive, RangeToInclusive};
+pub use self::range::{RangeInclusive, RangeToInclusive, RangeBounds, Bound};
 
 #[unstable(feature = "try_trait", issue = "42327")]
 pub use self::try::Try;
@@ -200,8 +199,5 @@ pub use self::try::Try;
 #[unstable(feature = "generator_trait", issue = "43122")]
 pub use self::generator::{Generator, GeneratorState};
 
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub use self::place::{Place, Placer, InPlace, Boxed, BoxPlace};
-
 #[unstable(feature = "coerce_unsized", issue = "27732")]
 pub use self::unsize::CoerceUnsized;
diff --git a/src/libcore/ops/place.rs b/src/libcore/ops/place.rs
deleted file mode 100644
index b3dcf4e7ee9..00000000000
--- a/src/libcore/ops/place.rs
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// Both `PLACE <- EXPR` and `box EXPR` desugar into expressions
-/// that allocate an intermediate "place" that holds uninitialized
-/// state.  The desugaring evaluates EXPR, and writes the result at
-/// the address returned by the `pointer` method of this trait.
-///
-/// A `Place` can be thought of as a special representation for a
-/// hypothetical `&uninit` reference (which Rust cannot currently
-/// express directly). That is, it represents a pointer to
-/// uninitialized storage.
-///
-/// The client is responsible for two steps: First, initializing the
-/// payload (it can access its address via `pointer`). Second,
-/// converting the agent to an instance of the owning pointer, via the
-/// appropriate `finalize` method (see the `InPlace`.
-///
-/// If evaluating EXPR fails, then it is up to the destructor for the
-/// implementation of Place to clean up any intermediate state
-/// (e.g. deallocate box storage, pop a stack, etc).
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub unsafe trait Place<Data: ?Sized> {
-    /// Returns the address where the input value will be written.
-    /// Note that the data at this address is generally uninitialized,
-    /// and thus one should use `ptr::write` for initializing it.
-    ///
-    /// This function must return a pointer through which a value
-    /// of type `Data` can be written.
-    fn pointer(&mut self) -> *mut Data;
-}
-
-/// Interface to implementations of  `PLACE <- EXPR`.
-///
-/// `PLACE <- EXPR` effectively desugars into:
-///
-/// ```
-/// # #![feature(placement_new_protocol, box_heap)]
-/// # use std::ops::{Placer, Place, InPlace};
-/// # #[allow(non_snake_case)]
-/// # fn main() {
-/// # let PLACE = std::boxed::HEAP;
-/// # let EXPR = 1;
-/// let p = PLACE;
-/// let mut place = Placer::make_place(p);
-/// let raw_place = Place::pointer(&mut place);
-/// let value = EXPR;
-/// unsafe {
-///     std::ptr::write(raw_place, value);
-///     InPlace::finalize(place)
-/// }
-/// # ; }
-/// ```
-///
-/// The type of `PLACE <- EXPR` is derived from the type of `PLACE`;
-/// if the type of `PLACE` is `P`, then the final type of the whole
-/// expression is `P::Place::Owner` (see the `InPlace` and `Boxed`
-/// traits).
-///
-/// Values for types implementing this trait usually are transient
-/// intermediate values (e.g. the return value of `Vec::emplace_back`)
-/// or `Copy`, since the `make_place` method takes `self` by value.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait Placer<Data: ?Sized> {
-    /// `Place` is the intermediate agent guarding the
-    /// uninitialized state for `Data`.
-    type Place: InPlace<Data>;
-
-    /// Creates a fresh place from `self`.
-    fn make_place(self) -> Self::Place;
-}
-
-/// Specialization of `Place` trait supporting `PLACE <- EXPR`.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait InPlace<Data: ?Sized>: Place<Data> {
-    /// `Owner` is the type of the end value of `PLACE <- EXPR`
-    ///
-    /// Note that when `PLACE <- EXPR` is solely used for
-    /// side-effecting an existing data-structure,
-    /// e.g. `Vec::emplace_back`, then `Owner` need not carry any
-    /// information at all (e.g. it can be the unit type `()` in that
-    /// case).
-    type Owner;
-
-    /// Converts self into the final value, shifting
-    /// deallocation/cleanup responsibilities (if any remain), over to
-    /// the returned instance of `Owner` and forgetting self.
-    unsafe fn finalize(self) -> Self::Owner;
-}
-
-/// Core trait for the `box EXPR` form.
-///
-/// `box EXPR` effectively desugars into:
-///
-/// ```
-/// # #![feature(placement_new_protocol)]
-/// # use std::ops::{BoxPlace, Place, Boxed};
-/// # #[allow(non_snake_case)]
-/// # fn main() {
-/// # let EXPR = 1;
-/// let mut place = BoxPlace::make_place();
-/// let raw_place = Place::pointer(&mut place);
-/// let value = EXPR;
-/// # let _: Box<_> =
-/// unsafe {
-///     ::std::ptr::write(raw_place, value);
-///     Boxed::finalize(place)
-/// }
-/// # ; }
-/// ```
-///
-/// The type of `box EXPR` is supplied from its surrounding
-/// context; in the above expansion, the result type `T` is used
-/// to determine which implementation of `Boxed` to use, and that
-/// `<T as Boxed>` in turn dictates determines which
-/// implementation of `BoxPlace` to use, namely:
-/// `<<T as Boxed>::Place as BoxPlace>`.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait Boxed {
-    /// The kind of data that is stored in this kind of box.
-    type Data;  /* (`Data` unused b/c cannot yet express below bound.) */
-    /// The place that will negotiate the storage of the data.
-    type Place: BoxPlace<Self::Data>;
-
-    /// Converts filled place into final owning value, shifting
-    /// deallocation/cleanup responsibilities (if any remain), over to
-    /// returned instance of `Self` and forgetting `filled`.
-    unsafe fn finalize(filled: Self::Place) -> Self;
-}
-
-/// Specialization of `Place` trait supporting `box EXPR`.
-#[unstable(feature = "placement_new_protocol", issue = "27779")]
-pub trait BoxPlace<Data: ?Sized> : Place<Data> {
-    /// Creates a globally fresh place.
-    fn make_place() -> Self;
-}
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index be51f5239b0..3f667407125 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -442,3 +442,267 @@ impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
 
 // RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
 // because underflow would be possible with (..0).into()
+
+/// An endpoint of a range of keys.
+///
+/// # Examples
+///
+/// `Bound`s are range endpoints:
+///
+/// ```
+/// #![feature(collections_range)]
+///
+/// use std::ops::Bound::*;
+/// use std::ops::RangeBounds;
+///
+/// assert_eq!((..100).start(), Unbounded);
+/// assert_eq!((1..12).start(), Included(&1));
+/// assert_eq!((1..12).end(), Excluded(&12));
+/// ```
+///
+/// Using a tuple of `Bound`s as an argument to [`BTreeMap::range`].
+/// Note that in most cases, it's better to use range syntax (`1..5`) instead.
+///
+/// ```
+/// use std::collections::BTreeMap;
+/// use std::ops::Bound::{Excluded, Included, Unbounded};
+///
+/// let mut map = BTreeMap::new();
+/// map.insert(3, "a");
+/// map.insert(5, "b");
+/// map.insert(8, "c");
+///
+/// for (key, value) in map.range((Excluded(3), Included(8))) {
+///     println!("{}: {}", key, value);
+/// }
+///
+/// assert_eq!(Some((&3, &"a")), map.range((Unbounded, Included(5))).next());
+/// ```
+///
+/// [`BTreeMap::range`]: ../../std/collections/btree_map/struct.BTreeMap.html#method.range
+#[stable(feature = "collections_bound", since = "1.17.0")]
+#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)]
+pub enum Bound<T> {
+    /// An inclusive bound.
+    #[stable(feature = "collections_bound", since = "1.17.0")]
+    Included(#[stable(feature = "collections_bound", since = "1.17.0")] T),
+    /// An exclusive bound.
+    #[stable(feature = "collections_bound", since = "1.17.0")]
+    Excluded(#[stable(feature = "collections_bound", since = "1.17.0")] T),
+    /// An infinite endpoint. Indicates that there is no bound in this direction.
+    #[stable(feature = "collections_bound", since = "1.17.0")]
+    Unbounded,
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+/// `RangeBounds` is implemented by Rust's built-in range types, produced
+/// by range syntax like `..`, `a..`, `..b` or `c..d`.
+pub trait RangeBounds<T: ?Sized> {
+    /// Start index bound.
+    ///
+    /// Returns the start value as a `Bound`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collections_range)]
+    ///
+    /// # fn main() {
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((..10).start(), Unbounded);
+    /// assert_eq!((3..10).start(), Included(&3));
+    /// # }
+    /// ```
+    fn start(&self) -> Bound<&T>;
+
+    /// End index bound.
+    ///
+    /// Returns the end value as a `Bound`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(collections_range)]
+    ///
+    /// # fn main() {
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((3..).end(), Unbounded);
+    /// assert_eq!((3..10).end(), Excluded(&10));
+    /// # }
+    /// ```
+    fn end(&self) -> Bound<&T>;
+}
+
+use self::Bound::{Excluded, Included, Unbounded};
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T: ?Sized> RangeBounds<T> for RangeFull {
+    fn start(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T> RangeBounds<T> for RangeFrom<T> {
+    fn start(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T> RangeBounds<T> for RangeTo<T> {
+    fn start(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end(&self) -> Bound<&T> {
+        Excluded(&self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T> RangeBounds<T> for Range<T> {
+    fn start(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end(&self) -> Bound<&T> {
+        Excluded(&self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T> RangeBounds<T> for RangeInclusive<T> {
+    fn start(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end(&self) -> Bound<&T> {
+        Included(&self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T> RangeBounds<T> for RangeToInclusive<T> {
+    fn start(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end(&self) -> Bound<&T> {
+        Included(&self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
+    fn start(&self) -> Bound<&T> {
+        match *self {
+            (Included(ref start), _) => Included(start),
+            (Excluded(ref start), _) => Excluded(start),
+            (Unbounded, _)           => Unbounded,
+        }
+    }
+
+    fn end(&self) -> Bound<&T> {
+        match *self {
+            (_, Included(ref end)) => Included(end),
+            (_, Excluded(ref end)) => Excluded(end),
+            (_, Unbounded)         => Unbounded,
+        }
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) {
+    fn start(&self) -> Bound<&T> {
+        self.0
+    }
+
+    fn end(&self) -> Bound<&T> {
+        self.1
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<'a, T> RangeBounds<T> for RangeFrom<&'a T> {
+    fn start(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<'a, T> RangeBounds<T> for RangeTo<&'a T> {
+    fn start(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end(&self) -> Bound<&T> {
+        Excluded(self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<'a, T> RangeBounds<T> for Range<&'a T> {
+    fn start(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end(&self) -> Bound<&T> {
+        Excluded(self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<'a, T> RangeBounds<T> for RangeInclusive<&'a T> {
+    fn start(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end(&self) -> Bound<&T> {
+        Included(self.end)
+    }
+}
+
+#[unstable(feature = "collections_range",
+           reason = "might be replaced with `Into<_>` and a type containing two `Bound` values",
+           issue = "30877")]
+impl<'a, T> RangeBounds<T> for RangeToInclusive<&'a T> {
+    fn start(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end(&self) -> Bound<&T> {
+        Included(self.end)
+    }
+}
diff --git a/src/libcore/ops/try.rs b/src/libcore/ops/try.rs
index 81e5cb5c350..ef6a8fb6a61 100644
--- a/src/libcore/ops/try.rs
+++ b/src/libcore/ops/try.rs
@@ -20,7 +20,7 @@
        any(from_method="from_error", from_method="from_ok"),
        from_desugaring="?"),
       message="the `?` operator can only be used in a \
-               function that returns `Result` \
+               function that returns `Result` or `Option` \
                (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="?"),
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 570f745f833..61ef6798b2e 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1188,6 +1188,16 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
                     None => None,
                 }
             }
+
+            #[inline]
+            fn size_hint(&self) -> (usize, Option<usize>) {
+                if self.found_none {
+                    (0, Some(0))
+                } else {
+                    let (_, upper) = self.iter.size_hint();
+                    (0, upper)
+                }
+            }
         }
 
         let mut adapter = Adapter { iter: iter.into_iter(), found_none: false };
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 6270e5892b3..5a54de06b5e 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -23,7 +23,7 @@ use fmt;
 use hash;
 use marker::{PhantomData, Unsize};
 use mem;
-use nonzero::NonZero;
+#[allow(deprecated)] use nonzero::NonZero;
 
 use cmp::Ordering::{self, Less, Equal, Greater};
 
@@ -669,7 +669,7 @@ impl<T: ?Sized> *const T {
     /// `mem::size_of::<T>()` then the result of the division is rounded towards
     /// zero.
     ///
-    /// This function returns `None` if `T` is a zero-sized typed.
+    /// This function returns `None` if `T` is a zero-sized type.
     ///
     /// # Examples
     ///
@@ -700,6 +700,124 @@ impl<T: ?Sized> *const T {
         }
     }
 
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// This function is the inverse of [`offset`].
+    ///
+    /// [`offset`]: #method.offset
+    /// [`wrapping_offset_from`]: #method.wrapping_offset_from
+    ///
+    /// # Safety
+    ///
+    /// If any of the following conditions are violated, the result is Undefined
+    /// Behavior:
+    ///
+    /// * Both the starting and other pointer must be either in bounds or one
+    ///   byte past the end of the same allocated object.
+    ///
+    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
+    ///
+    /// * The distance between the pointers, in bytes, must be an exact multiple
+    ///   of the size of `T`.
+    ///
+    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
+    ///
+    /// The compiler and standard library generally try to ensure allocations
+    /// never reach a size where an offset is a concern. For instance, `Vec`
+    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
+    /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
+    ///
+    /// Most platforms fundamentally can't even construct such an allocation.
+    /// For instance, no known 64-bit platform can ever serve a request
+    /// 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
+    /// mapped files *may* be too large to handle with this function.
+    ///
+    /// Consider using [`wrapping_offset_from`] instead if these constraints are
+    /// difficult to satisfy. The only advantage of this method is that it
+    /// enables more aggressive compiler optimizations.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a Zero-Sized Type ("ZST").
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_offset_from)]
+    ///
+    /// let a = [0; 5];
+    /// let ptr1: *const i32 = &a[1];
+    /// let ptr2: *const i32 = &a[3];
+    /// unsafe {
+    ///     assert_eq!(ptr2.offset_from(ptr1), 2);
+    ///     assert_eq!(ptr1.offset_from(ptr2), -2);
+    ///     assert_eq!(ptr1.offset(2), ptr2);
+    ///     assert_eq!(ptr2.offset(-2), ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "ptr_offset_from", issue = "41079")]
+    #[inline]
+    pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+        let pointee_size = mem::size_of::<T>();
+        assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+        // This is the same sequence that Clang emits for pointer subtraction.
+        // It can be neither `nsw` nor `nuw` because the input is treated as
+        // unsigned but then the output is treated as signed, so neither works.
+        let d = isize::wrapping_sub(self as _, origin as _);
+        intrinsics::exact_div(d, pointee_size as _)
+    }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers is not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// Though this method is safe for any two pointers, note that its result
+    /// will be mostly useless if the two pointers aren't into the same allocated
+    /// object, for example if they point to two different local variables.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a zero-sized type.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_wrapping_offset_from)]
+    ///
+    /// let a = [0; 5];
+    /// let ptr1: *const i32 = &a[1];
+    /// let ptr2: *const i32 = &a[3];
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
+    /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
+    /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
+    ///
+    /// let ptr1: *const i32 = 3 as _;
+    /// let ptr2: *const i32 = 13 as _;
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// ```
+    #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
+    #[inline]
+    pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+        let pointee_size = mem::size_of::<T>();
+        assert!(0 < pointee_size && pointee_size <= isize::max_value() as usize);
+
+        let d = isize::wrapping_sub(self as _, origin as _);
+        d.wrapping_div(pointee_size as _)
+    }
+
     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
     ///
     /// `count` is in units of T; e.g. a `count` of 3 represents a pointer
@@ -1316,7 +1434,7 @@ impl<T: ?Sized> *mut T {
     /// `mem::size_of::<T>()` then the result of the division is rounded towards
     /// zero.
     ///
-    /// This function returns `None` if `T` is a zero-sized typed.
+    /// This function returns `None` if `T` is a zero-sized type.
     ///
     /// # Examples
     ///
@@ -1347,6 +1465,113 @@ impl<T: ?Sized> *mut T {
         }
     }
 
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// This function is the inverse of [`offset`].
+    ///
+    /// [`offset`]: #method.offset-1
+    /// [`wrapping_offset_from`]: #method.wrapping_offset_from-1
+    ///
+    /// # Safety
+    ///
+    /// If any of the following conditions are violated, the result is Undefined
+    /// Behavior:
+    ///
+    /// * Both the starting and other pointer must be either in bounds or one
+    ///   byte past the end of the same allocated object.
+    ///
+    /// * The distance between the pointers, **in bytes**, cannot overflow an `isize`.
+    ///
+    /// * The distance between the pointers, in bytes, must be an exact multiple
+    ///   of the size of `T`.
+    ///
+    /// * The distance being in bounds cannot rely on "wrapping around" the address space.
+    ///
+    /// The compiler and standard library generally try to ensure allocations
+    /// never reach a size where an offset is a concern. For instance, `Vec`
+    /// and `Box` ensure they never allocate more than `isize::MAX` bytes, so
+    /// `ptr_into_vec.offset_from(vec.as_ptr())` is always safe.
+    ///
+    /// Most platforms fundamentally can't even construct such an allocation.
+    /// For instance, no known 64-bit platform can ever serve a request
+    /// 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
+    /// mapped files *may* be too large to handle with this function.
+    ///
+    /// Consider using [`wrapping_offset_from`] instead if these constraints are
+    /// difficult to satisfy. The only advantage of this method is that it
+    /// enables more aggressive compiler optimizations.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a Zero-Sized Type ("ZST").
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_offset_from)]
+    ///
+    /// let mut a = [0; 5];
+    /// let ptr1: *mut i32 = &mut a[1];
+    /// let ptr2: *mut i32 = &mut a[3];
+    /// unsafe {
+    ///     assert_eq!(ptr2.offset_from(ptr1), 2);
+    ///     assert_eq!(ptr1.offset_from(ptr2), -2);
+    ///     assert_eq!(ptr1.offset(2), ptr2);
+    ///     assert_eq!(ptr2.offset(-2), ptr1);
+    /// }
+    /// ```
+    #[unstable(feature = "ptr_offset_from", issue = "41079")]
+    #[inline]
+    pub unsafe fn offset_from(self, origin: *const T) -> isize where T: Sized {
+        (self as *const T).offset_from(origin)
+    }
+
+    /// Calculates the distance between two pointers. The returned value is in
+    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    ///
+    /// If the address different between the two pointers is not a multiple of
+    /// `mem::size_of::<T>()` then the result of the division is rounded towards
+    /// zero.
+    ///
+    /// Though this method is safe for any two pointers, note that its result
+    /// will be mostly useless if the two pointers aren't into the same allocated
+    /// object, for example if they point to two different local variables.
+    ///
+    /// # Panics
+    ///
+    /// This function panics if `T` is a zero-sized type.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(ptr_wrapping_offset_from)]
+    ///
+    /// let mut a = [0; 5];
+    /// let ptr1: *mut i32 = &mut a[1];
+    /// let ptr2: *mut i32 = &mut a[3];
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// assert_eq!(ptr1.wrapping_offset_from(ptr2), -2);
+    /// assert_eq!(ptr1.wrapping_offset(2), ptr2);
+    /// assert_eq!(ptr2.wrapping_offset(-2), ptr1);
+    ///
+    /// let ptr1: *mut i32 = 3 as _;
+    /// let ptr2: *mut i32 = 13 as _;
+    /// assert_eq!(ptr2.wrapping_offset_from(ptr1), 2);
+    /// ```
+    #[unstable(feature = "ptr_wrapping_offset_from", issue = "41079")]
+    #[inline]
+    pub fn wrapping_offset_from(self, origin: *const T) -> isize where T: Sized {
+        (self as *const T).wrapping_offset_from(origin)
+    }
+
     /// Computes the byte offset that needs to be applied in order to
     /// make the pointer aligned to `align`.
     /// If it is not possible to align the pointer, the implementation returns
@@ -2285,6 +2510,7 @@ impl<T: ?Sized> PartialOrd for *mut T {
 #[unstable(feature = "ptr_internals", issue = "0",
            reason = "use NonNull instead and consider PhantomData<T> \
                      (if you also use #[may_dangle]), Send, and/or Sync")]
+#[allow(deprecated)]
 pub struct Unique<T: ?Sized> {
     pointer: NonZero<*const T>,
     // NOTE: this marker has no consequences for variance, but is necessary
@@ -2332,6 +2558,7 @@ impl<T: Sized> Unique<T> {
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
+#[allow(deprecated)]
 impl<T: ?Sized> Unique<T> {
     /// Creates a new `Unique`.
     ///
@@ -2339,17 +2566,21 @@ impl<T: ?Sized> Unique<T> {
     ///
     /// `ptr` must be non-null.
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
+        Unique { pointer: NonZero(ptr as _), _marker: PhantomData }
     }
 
     /// Creates a new `Unique` if `ptr` is non-null.
     pub fn new(ptr: *mut T) -> Option<Self> {
-        NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData })
+        if !ptr.is_null() {
+            Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData })
+        } else {
+            None
+        }
     }
 
     /// Acquires the underlying `*mut` pointer.
     pub fn as_ptr(self) -> *mut T {
-        self.pointer.get() as *mut T
+        self.pointer.0 as *mut T
     }
 
     /// Dereferences the content.
@@ -2392,16 +2623,18 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
+#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
     fn from(reference: &'a mut T) -> Self {
-        Unique { pointer: NonZero::from(reference), _marker: PhantomData }
+        Unique { pointer: NonZero(reference as _), _marker: PhantomData }
     }
 }
 
 #[unstable(feature = "ptr_internals", issue = "0")]
+#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
     fn from(reference: &'a T) -> Self {
-        Unique { pointer: NonZero::from(reference), _marker: PhantomData }
+        Unique { pointer: NonZero(reference as _), _marker: PhantomData }
     }
 }
 
@@ -2412,11 +2645,6 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
     }
 }
 
-/// Previous name of `NonNull`.
-#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")]
-#[unstable(feature = "shared", issue = "27730")]
-pub type Shared<T> = NonNull<T>;
-
 /// `*mut T` but non-zero and covariant.
 ///
 /// This is often the correct thing to use when building data structures using
@@ -2425,7 +2653,7 @@ pub type Shared<T> = NonNull<T>;
 ///
 /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
 /// is never dereferenced. This is so that enums may use this forbidden value
-/// as a discriminant -- `Option<NonNull<T>>` has the same size as `NonNull<T>`.
+/// as a discriminant -- `Option<NonNull<T>>` has the same size as `*mut T`.
 /// However the pointer may still dangle if it isn't dereferenced.
 ///
 /// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
@@ -2436,7 +2664,7 @@ pub type Shared<T> = NonNull<T>;
 /// provide a public API that follows the normal shared XOR mutable rules of Rust.
 #[stable(feature = "nonnull", since = "1.25.0")]
 pub struct NonNull<T: ?Sized> {
-    pointer: NonZero<*const T>,
+    #[allow(deprecated)] pointer: NonZero<*const T>,
 }
 
 /// `NonNull` pointers are not `Send` because the data they reference may be aliased.
@@ -2463,6 +2691,7 @@ impl<T: Sized> NonNull<T> {
     }
 }
 
+#[allow(deprecated)]
 impl<T: ?Sized> NonNull<T> {
     /// Creates a new `NonNull`.
     ///
@@ -2471,19 +2700,23 @@ impl<T: ?Sized> NonNull<T> {
     /// `ptr` must be non-null.
     #[stable(feature = "nonnull", since = "1.25.0")]
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
-        NonNull { pointer: NonZero::new_unchecked(ptr) }
+        NonNull { pointer: NonZero(ptr as _) }
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
     #[stable(feature = "nonnull", since = "1.25.0")]
     pub fn new(ptr: *mut T) -> Option<Self> {
-        NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz })
+        if !ptr.is_null() {
+            Some(NonNull { pointer: NonZero(ptr as _) })
+        } else {
+            None
+        }
     }
 
     /// Acquires the underlying `*mut` pointer.
     #[stable(feature = "nonnull", since = "1.25.0")]
     pub fn as_ptr(self) -> *mut T {
-        self.pointer.get() as *mut T
+        self.pointer.0 as *mut T
     }
 
     /// Dereferences the content.
@@ -2581,15 +2814,17 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
 }
 
 #[stable(feature = "nonnull", since = "1.25.0")]
+#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
     fn from(reference: &'a mut T) -> Self {
-        NonNull { pointer: NonZero::from(reference) }
+        NonNull { pointer: NonZero(reference as _) }
     }
 }
 
 #[stable(feature = "nonnull", since = "1.25.0")]
+#[allow(deprecated)]
 impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
     fn from(reference: &'a T) -> Self {
-        NonNull { pointer: NonZero::from(reference) }
+        NonNull { pointer: NonZero(reference as _) }
     }
 }
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 9cf862bd936..1185b7acaae 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -165,6 +165,37 @@ Section: Creating a string
 ///
 /// [`String`]: ../../std/string/struct.String.html#method.from_utf8
 /// [`&str`]: ../../std/str/fn.from_utf8.html
+///
+/// # Examples
+///
+/// This error type’s methods can be used to create functionality
+/// similar to `String::from_utf8_lossy` without allocating heap memory:
+///
+/// ```
+/// fn from_utf8_lossy<F>(mut input: &[u8], mut push: F) where F: FnMut(&str) {
+///     loop {
+///         match ::std::str::from_utf8(input) {
+///             Ok(valid) => {
+///                 push(valid);
+///                 break
+///             }
+///             Err(error) => {
+///                 let (valid, after_valid) = input.split_at(error.valid_up_to());
+///                 unsafe {
+///                     push(::std::str::from_utf8_unchecked(valid))
+///                 }
+///                 push("\u{FFFD}");
+///
+///                 if let Some(invalid_sequence_length) = error.error_len() {
+///                     input = &after_valid[invalid_sequence_length..]
+///                 } else {
+///                     break
+///                 }
+///             }
+///         }
+///     }
+/// }
+/// ```
 #[derive(Copy, Eq, PartialEq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Utf8Error {
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 25827edee7d..d336934ec72 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -205,8 +205,11 @@ pub enum Ordering {
     /// [`Release`]: http://llvm.org/docs/Atomics.html#release
     #[stable(feature = "rust1", since = "1.0.0")]
     Acquire,
-    /// When coupled with a load, uses [`Acquire`] ordering, and with a store
-    /// [`Release`] ordering.
+    /// Has the effects of both [`Acquire`] and [`Release`] together.
+    ///
+    /// This ordering is only applicable for operations that combine both loads and stores.
+    ///
+    /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
     ///
     /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire
     /// [`Release`]: http://llvm.org/docs/Atomics.html#release
@@ -948,6 +951,8 @@ macro_rules! atomic_int {
      $stable_from:meta,
      $stable_nand:meta,
      $s_int_type:expr, $int_ref:expr,
+     $extra_feature:expr,
+     $min_fn:ident, $max_fn:ident,
      $int_type:ident $atomic_type:ident $atomic_init:ident) => {
         /// An integer type which can be safely shared between threads.
         ///
@@ -959,12 +964,7 @@ macro_rules! atomic_int {
         /// ). 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>,
@@ -1001,396 +1001,549 @@ macro_rules! atomic_int {
         unsafe impl Sync for $atomic_type {}
 
         impl $atomic_type {
-            /// Creates a new atomic integer.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::AtomicIsize;
-            ///
-            /// let atomic_forty_two  = AtomicIsize::new(42);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub const fn new(v: $int_type) -> Self {
-                $atomic_type {v: UnsafeCell::new(v)}
+            doc_comment! {
+                concat!("Creates a new atomic integer.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
+
+let atomic_forty_two = ", stringify!($atomic_type), "::new(42);
+```"),
+                #[inline]
+                #[$stable]
+                pub const fn new(v: $int_type) -> Self {
+                    $atomic_type {v: UnsafeCell::new(v)}
+                }
             }
 
-            /// Returns a mutable reference to the underlying integer.
-            ///
-            /// This is safe because the mutable reference guarantees that no other threads are
-            /// concurrently accessing the atomic data.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let mut some_isize = AtomicIsize::new(10);
-            /// assert_eq!(*some_isize.get_mut(), 10);
-            /// *some_isize.get_mut() = 5;
-            /// assert_eq!(some_isize.load(Ordering::SeqCst), 5);
-            /// ```
-            #[inline]
-            #[$stable_access]
-            pub fn get_mut(&mut self) -> &mut $int_type {
-                unsafe { &mut *self.v.get() }
+            doc_comment! {
+                concat!("Returns a mutable reference to the underlying integer.
+
+This is safe because the mutable reference guarantees that no other threads are
+concurrently accessing the atomic data.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let mut some_var = ", stringify!($atomic_type), "::new(10);
+assert_eq!(*some_var.get_mut(), 10);
+*some_var.get_mut() = 5;
+assert_eq!(some_var.load(Ordering::SeqCst), 5);
+```"),
+                #[inline]
+                #[$stable_access]
+                pub fn get_mut(&mut self) -> &mut $int_type {
+                    unsafe { &mut *self.v.get() }
+                }
             }
 
-            /// Consumes the atomic and returns the contained value.
-            ///
-            /// This is safe because passing `self` by value guarantees that no other threads are
-            /// concurrently accessing the atomic data.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::AtomicIsize;
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            /// assert_eq!(some_isize.into_inner(), 5);
-            /// ```
-            #[inline]
-            #[$stable_access]
-            pub fn into_inner(self) -> $int_type {
-                self.v.into_inner()
+            doc_comment! {
+                concat!("Consumes the atomic and returns the contained value.
+
+This is safe because passing `self` by value guarantees that no other threads are
+concurrently accessing the atomic data.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::", stringify!($atomic_type), ";
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+assert_eq!(some_var.into_inner(), 5);
+```"),
+                #[inline]
+                #[$stable_access]
+                pub fn into_inner(self) -> $int_type {
+                    self.v.into_inner()
+                }
             }
 
-            /// Loads a value from the atomic integer.
-            ///
-            /// `load` takes an [`Ordering`] argument which describes the memory ordering of this
-            /// operation.
-            ///
-            /// # Panics
-            ///
-            /// Panics if `order` is [`Release`] or [`AcqRel`].
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            /// [`Release`]: enum.Ordering.html#variant.Release
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 5);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn load(&self, order: Ordering) -> $int_type {
-                unsafe { atomic_load(self.v.get(), order) }
+            doc_comment! {
+                concat!("Loads a value from the atomic integer.
+
+`load` takes an [`Ordering`] argument which describes the memory ordering of this operation.
+
+# Panics
+
+Panics if `order` is [`Release`] or [`AcqRel`].
+
+[`Ordering`]: enum.Ordering.html
+[`Release`]: enum.Ordering.html#variant.Release
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.load(Ordering::Relaxed), 5);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn load(&self, order: Ordering) -> $int_type {
+                    unsafe { atomic_load(self.v.get(), order) }
+                }
             }
 
-            /// Stores a value into the atomic integer.
-            ///
-            /// `store` takes an [`Ordering`] argument which describes the memory ordering of this
-            /// operation.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// some_isize.store(10, Ordering::Relaxed);
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            /// ```
-            ///
-            /// # Panics
-            ///
-            /// Panics if `order` is [`Acquire`] or [`AcqRel`].
-            ///
-            /// [`Acquire`]: enum.Ordering.html#variant.Acquire
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            #[inline]
-            #[$stable]
-            pub fn store(&self, val: $int_type, order: Ordering) {
-                unsafe { atomic_store(self.v.get(), val, order); }
+            doc_comment! {
+                concat!("Stores a value into the atomic integer.
+
+`store` takes an [`Ordering`] argument which describes the memory ordering of this operation.
+
+[`Ordering`]: enum.Ordering.html
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+some_var.store(10, Ordering::Relaxed);
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+```
+
+# Panics
+
+Panics if `order` is [`Acquire`] or [`AcqRel`].
+
+[`Acquire`]: enum.Ordering.html#variant.Acquire
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel"),
+                #[inline]
+                #[$stable]
+                pub fn store(&self, val: $int_type, order: Ordering) {
+                    unsafe { atomic_store(self.v.get(), val, order); }
+                }
             }
 
-            /// Stores a value into the atomic integer, returning the previous value.
-            ///
-            /// `swap` takes an [`Ordering`] argument which describes the memory ordering of this
-            /// operation.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.swap(10, Ordering::Relaxed), 5);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_swap(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Stores a value into the atomic integer, returning the previous value.
+
+`swap` takes an [`Ordering`] argument which describes the memory ordering of this operation.
+
+[`Ordering`]: enum.Ordering.html
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.swap(10, Ordering::Relaxed), 5);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_swap(self.v.get(), val, order) }
+                }
             }
 
-            /// Stores a value into the atomic integer 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.
-            ///
-            /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory
-            /// ordering of this operation.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.compare_and_swap(5, 10, Ordering::Relaxed), 5);
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            ///
-            /// assert_eq!(some_isize.compare_and_swap(6, 12, Ordering::Relaxed), 10);
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn compare_and_swap(&self,
-                                    current: $int_type,
-                                    new: $int_type,
-                                    order: Ordering) -> $int_type {
-                match self.compare_exchange(current,
-                                            new,
-                                            order,
-                                            strongest_failure_ordering(order)) {
-                    Ok(x) => x,
-                    Err(x) => x,
+            doc_comment! {
+                concat!("Stores a value into the atomic integer 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.
+
+`compare_and_swap` also takes an [`Ordering`] argument which describes the memory
+ordering of this operation.
+
+[`Ordering`]: enum.Ordering.html
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.compare_and_swap(5, 10, Ordering::Relaxed), 5);
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+
+assert_eq!(some_var.compare_and_swap(6, 12, Ordering::Relaxed), 10);
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn compare_and_swap(&self,
+                                        current: $int_type,
+                                        new: $int_type,
+                                        order: Ordering) -> $int_type {
+                    match self.compare_exchange(current,
+                                                new,
+                                                order,
+                                                strongest_failure_ordering(order)) {
+                        Ok(x) => x,
+                        Err(x) => x,
+                    }
                 }
             }
 
-            /// Stores a value into the atomic integer 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`.
-            ///
-            /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory
-            /// ordering of this operation. The first describes the required ordering if
-            /// the operation succeeds while the second describes the required ordering when
-            /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
-            /// must be equivalent or weaker than the success ordering.
-            ///
-            /// [`Ordering`]: enum.Ordering.html
-            /// [`Release`]: enum.Ordering.html#variant.Release
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let some_isize = AtomicIsize::new(5);
-            ///
-            /// assert_eq!(some_isize.compare_exchange(5, 10,
-            ///                                        Ordering::Acquire,
-            ///                                        Ordering::Relaxed),
-            ///            Ok(5));
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            ///
-            /// assert_eq!(some_isize.compare_exchange(6, 12,
-            ///                                        Ordering::SeqCst,
-            ///                                        Ordering::Acquire),
-            ///            Err(10));
-            /// assert_eq!(some_isize.load(Ordering::Relaxed), 10);
-            /// ```
-            #[inline]
-            #[$stable_cxchg]
-            pub fn compare_exchange(&self,
-                                    current: $int_type,
-                                    new: $int_type,
-                                    success: Ordering,
-                                    failure: Ordering) -> Result<$int_type, $int_type> {
-                unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
+            doc_comment! {
+                concat!("Stores a value into the atomic integer 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`.
+
+`compare_exchange` takes two [`Ordering`] arguments to describe the memory
+ordering of this operation. The first describes the required ordering if
+the operation succeeds while the second describes the required ordering when
+the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
+must be equivalent or weaker than the success ordering.
+
+[`Ordering`]: enum.Ordering.html
+[`Release`]: enum.Ordering.html#variant.Release
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let some_var = ", stringify!($atomic_type), "::new(5);
+
+assert_eq!(some_var.compare_exchange(5, 10,
+                                     Ordering::Acquire,
+                                     Ordering::Relaxed),
+           Ok(5));
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+
+assert_eq!(some_var.compare_exchange(6, 12,
+                                     Ordering::SeqCst,
+                                     Ordering::Acquire),
+           Err(10));
+assert_eq!(some_var.load(Ordering::Relaxed), 10);
+```"),
+                #[inline]
+                #[$stable_cxchg]
+                pub fn compare_exchange(&self,
+                                        current: $int_type,
+                                        new: $int_type,
+                                        success: Ordering,
+                                        failure: Ordering) -> Result<$int_type, $int_type> {
+                    unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) }
+                }
             }
 
-            /// Stores a value into the atomic integer 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 return value is a result indicating whether the new value was
-            /// written and containing the previous value.
-            ///
-            /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
-            /// ordering of this operation. The first describes the required ordering if the
-            /// operation succeeds while the second describes the required ordering when the
-            /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
-            /// must be equivalent or weaker than the success ordering.
-            ///
-            /// [`compare_exchange`]: #method.compare_exchange
-            /// [`Ordering`]: enum.Ordering.html
-            /// [`Release`]: enum.Ordering.html#variant.Release
-            /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let val = AtomicIsize::new(4);
-            ///
-            /// let mut old = val.load(Ordering::Relaxed);
-            /// loop {
-            ///     let new = old * 2;
-            ///     match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
-            ///         Ok(_) => break,
-            ///         Err(x) => old = x,
-            ///     }
-            /// }
-            /// ```
-            #[inline]
-            #[$stable_cxchg]
-            pub fn compare_exchange_weak(&self,
-                                         current: $int_type,
-                                         new: $int_type,
-                                         success: Ordering,
-                                         failure: Ordering) -> Result<$int_type, $int_type> {
-                unsafe {
-                    atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
+            doc_comment! {
+                concat!("Stores a value into the atomic integer 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 return value is a result indicating whether the new value was
+written and containing the previous value.
+
+`compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory
+ordering of this operation. The first describes the required ordering if the
+operation succeeds while the second describes the required ordering when the
+operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and
+must be equivalent or weaker than the success ordering.
+
+[`compare_exchange`]: #method.compare_exchange
+[`Ordering`]: enum.Ordering.html
+[`Release`]: enum.Ordering.html#variant.Release
+[`AcqRel`]: enum.Ordering.html#variant.AcqRel
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let val = ", stringify!($atomic_type), "::new(4);
+
+let mut old = val.load(Ordering::Relaxed);
+loop {
+    let new = old * 2;
+    match val.compare_exchange_weak(old, new, Ordering::SeqCst, Ordering::Relaxed) {
+        Ok(_) => break,
+        Err(x) => old = x,
+    }
+}
+```"),
+                #[inline]
+                #[$stable_cxchg]
+                pub fn compare_exchange_weak(&self,
+                                             current: $int_type,
+                                             new: $int_type,
+                                             success: Ordering,
+                                             failure: Ordering) -> Result<$int_type, $int_type> {
+                    unsafe {
+                        atomic_compare_exchange_weak(self.v.get(), current, new, success, failure)
+                    }
                 }
             }
 
-            /// Adds to the current value, returning the previous value.
-            ///
-            /// This operation wraps around on overflow.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0);
-            /// assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 10);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_add(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Adds to the current value, returning the previous value.
+
+This operation wraps around on overflow.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0);
+assert_eq!(foo.fetch_add(10, Ordering::SeqCst), 0);
+assert_eq!(foo.load(Ordering::SeqCst), 10);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_add(self.v.get(), val, order) }
+                }
             }
 
-            /// Subtracts from the current value, returning the previous value.
-            ///
-            /// This operation wraps around on overflow.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0);
-            /// assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 0);
-            /// assert_eq!(foo.load(Ordering::SeqCst), -10);
-            /// ```
-            #[inline]
-            #[$stable]
-            pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_sub(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Subtracts from the current value, returning the previous value.
+
+This operation wraps around on overflow.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(20);
+assert_eq!(foo.fetch_sub(10, Ordering::SeqCst), 20);
+assert_eq!(foo.load(Ordering::SeqCst), 10);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_sub(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "and" with the current value.
-            ///
-            /// Performs a bitwise "and" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0b101101);
-            /// assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
-            #[inline]
-            #[$stable]
-            pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_and(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"and\" with the current value.
+
+Performs a bitwise \"and\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0b101101);
+assert_eq!(foo.fetch_and(0b110011, Ordering::SeqCst), 0b101101);
+assert_eq!(foo.load(Ordering::SeqCst), 0b100001);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_and(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "nand" with the current value.
-            ///
-            /// Performs a bitwise "nand" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// #![feature(atomic_nand)]
-            ///
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0xf731);
-            /// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731);
-            /// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f));
-            #[inline]
-            #[$stable_nand]
-            pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_nand(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"nand\" with the current value.
+
+Performs a bitwise \"nand\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "#![feature(atomic_nand)]
+
+use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0x13);
+assert_eq!(foo.fetch_nand(0x31, Ordering::SeqCst), 0x13);
+assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31));
+```"),
+                #[inline]
+                #[$stable_nand]
+                pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_nand(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "or" with the current value.
-            ///
-            /// Performs a bitwise "or" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0b101101);
-            /// assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
-            #[inline]
-            #[$stable]
-            pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_or(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"or\" with the current value.
+
+Performs a bitwise \"or\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0b101101);
+assert_eq!(foo.fetch_or(0b110011, Ordering::SeqCst), 0b101101);
+assert_eq!(foo.load(Ordering::SeqCst), 0b111111);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_or(self.v.get(), val, order) }
+                }
             }
 
-            /// Bitwise "xor" with the current value.
-            ///
-            /// Performs a bitwise "xor" operation on the current value and the argument `val`, and
-            /// sets the new value to the result.
-            ///
-            /// Returns the previous value.
-            ///
-            /// # Examples
-            ///
-            /// ```
-            /// use std::sync::atomic::{AtomicIsize, Ordering};
-            ///
-            /// let foo = AtomicIsize::new(0b101101);
-            /// assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
-            /// assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
-            #[inline]
-            #[$stable]
-            pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
-                unsafe { atomic_xor(self.v.get(), val, order) }
+            doc_comment! {
+                concat!("Bitwise \"xor\" with the current value.
+
+Performs a bitwise \"xor\" operation on the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(0b101101);
+assert_eq!(foo.fetch_xor(0b110011, Ordering::SeqCst), 0b101101);
+assert_eq!(foo.load(Ordering::SeqCst), 0b011110);
+```"),
+                #[inline]
+                #[$stable]
+                pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { atomic_xor(self.v.get(), val, order) }
+                }
+            }
+
+            doc_comment! {
+                concat!("Fetches the value, and applies a function to it that returns an optional
+new value. Returns a `Result` (`Ok(_)` if the function returned `Some(_)`, else `Err(_)`) of the
+previous value.
+
+Note: This may call the function multiple times if the value has been changed from other threads in
+the meantime, as long as the function returns `Some(_)`, but the function will have been applied
+but once to the stored value.
+
+# Examples
+
+```rust
+#![feature(no_more_cas)]
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let x = ", stringify!($atomic_type), "::new(7);
+assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7));
+assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7));
+assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(8));
+assert_eq!(x.load(Ordering::SeqCst), 9);
+```"),
+                #[inline]
+                #[unstable(feature = "no_more_cas",
+                       reason = "no more CAS loops in user code",
+                       issue = "48655")]
+                pub fn fetch_update<F>(&self,
+                                       mut f: F,
+                                       fetch_order: Ordering,
+                                       set_order: Ordering) -> Result<$int_type, $int_type>
+                where F: FnMut($int_type) -> Option<$int_type> {
+                    let mut prev = self.load(fetch_order);
+                    while let Some(next) = f(prev) {
+                        match self.compare_exchange_weak(prev, next, set_order, fetch_order) {
+                            x @ Ok(_) => return x,
+                            Err(next_prev) => prev = next_prev
+                        }
+                    }
+                    Err(prev)
+                }
+            }
+
+            doc_comment! {
+                concat!("Maximum with the current value.
+
+Finds the maximum of the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+#![feature(atomic_min_max)]
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(23);
+assert_eq!(foo.fetch_max(42, Ordering::SeqCst), 23);
+assert_eq!(foo.load(Ordering::SeqCst), 42);
+```
+
+If you want to obtain the maximum value in one step, you can use the following:
+
+```
+#![feature(atomic_min_max)]
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(23);
+let bar = 42;
+let max_foo = foo.fetch_max(bar, Ordering::SeqCst).max(bar);
+assert!(max_foo == 42);
+```"),
+                #[inline]
+                #[unstable(feature = "atomic_min_max",
+                       reason = "easier and faster min/max than writing manual CAS loop",
+                       issue = "48655")]
+                pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { $max_fn(self.v.get(), val, order) }
+                }
+            }
+
+            doc_comment! {
+                concat!("Minimum with the current value.
+
+Finds the minimum of the current value and the argument `val`, and
+sets the new value to the result.
+
+Returns the previous value.
+
+# Examples
+
+```
+#![feature(atomic_min_max)]
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(23);
+assert_eq!(foo.fetch_min(42, Ordering::Relaxed), 23);
+assert_eq!(foo.load(Ordering::Relaxed), 23);
+assert_eq!(foo.fetch_min(22, Ordering::Relaxed), 23);
+assert_eq!(foo.load(Ordering::Relaxed), 22);
+```
+
+If you want to obtain the minimum value in one step, you can use the following:
+
+```
+#![feature(atomic_min_max)]
+", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
+
+let foo = ", stringify!($atomic_type), "::new(23);
+let bar = 12;
+let min_foo = foo.fetch_min(bar, Ordering::SeqCst).min(bar);
+assert_eq!(min_foo, 12);
+```"),
+                #[inline]
+                #[unstable(feature = "atomic_min_max",
+                       reason = "easier and faster min/max than writing manual CAS loop",
+                       issue = "48655")]
+                pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type {
+                    unsafe { $min_fn(self.v.get(), val, order) }
+                }
             }
+
         }
     }
 }
@@ -1404,6 +1557,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i8", "../../../std/primitive.i8.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_min, atomic_max,
     i8 AtomicI8 ATOMIC_I8_INIT
 }
 #[cfg(target_has_atomic = "8")]
@@ -1415,6 +1570,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u8", "../../../std/primitive.u8.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_umin, atomic_umax,
     u8 AtomicU8 ATOMIC_U8_INIT
 }
 #[cfg(target_has_atomic = "16")]
@@ -1426,6 +1583,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i16", "../../../std/primitive.i16.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_min, atomic_max,
     i16 AtomicI16 ATOMIC_I16_INIT
 }
 #[cfg(target_has_atomic = "16")]
@@ -1437,6 +1596,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u16", "../../../std/primitive.u16.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_umin, atomic_umax,
     u16 AtomicU16 ATOMIC_U16_INIT
 }
 #[cfg(target_has_atomic = "32")]
@@ -1448,6 +1609,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i32", "../../../std/primitive.i32.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_min, atomic_max,
     i32 AtomicI32 ATOMIC_I32_INIT
 }
 #[cfg(target_has_atomic = "32")]
@@ -1459,6 +1622,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u32", "../../../std/primitive.u32.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_umin, atomic_umax,
     u32 AtomicU32 ATOMIC_U32_INIT
 }
 #[cfg(target_has_atomic = "64")]
@@ -1470,6 +1635,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "i64", "../../../std/primitive.i64.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_min, atomic_max,
     i64 AtomicI64 ATOMIC_I64_INIT
 }
 #[cfg(target_has_atomic = "64")]
@@ -1481,6 +1648,8 @@ atomic_int! {
     unstable(feature = "integer_atomics", issue = "32976"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "u64", "../../../std/primitive.u64.html",
+    "#![feature(integer_atomics)]\n\n",
+    atomic_umin, atomic_umax,
     u64 AtomicU64 ATOMIC_U64_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
@@ -1492,6 +1661,8 @@ atomic_int!{
     stable(feature = "atomic_from", since = "1.23.0"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "isize", "../../../std/primitive.isize.html",
+    "",
+    atomic_min, atomic_max,
     isize AtomicIsize ATOMIC_ISIZE_INIT
 }
 #[cfg(target_has_atomic = "ptr")]
@@ -1503,6 +1674,8 @@ atomic_int!{
     stable(feature = "atomic_from", since = "1.23.0"),
     unstable(feature = "atomic_nand", issue = "13226"),
     "usize", "../../../std/primitive.usize.html",
+    "",
+    atomic_umin, atomic_umax,
     usize AtomicUsize ATOMIC_USIZE_INIT
 }
 
@@ -1680,6 +1853,58 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
     }
 }
 
+/// returns the max value (signed comparison)
+#[inline]
+unsafe fn atomic_max<T>(dst: *mut T, val: T, order: Ordering) -> T {
+    match order {
+        Acquire => intrinsics::atomic_max_acq(dst, val),
+        Release => intrinsics::atomic_max_rel(dst, val),
+        AcqRel => intrinsics::atomic_max_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_max_relaxed(dst, val),
+        SeqCst => intrinsics::atomic_max(dst, val),
+        __Nonexhaustive => panic!("invalid memory ordering"),
+    }
+}
+
+/// returns the min value (signed comparison)
+#[inline]
+unsafe fn atomic_min<T>(dst: *mut T, val: T, order: Ordering) -> T {
+    match order {
+        Acquire => intrinsics::atomic_min_acq(dst, val),
+        Release => intrinsics::atomic_min_rel(dst, val),
+        AcqRel => intrinsics::atomic_min_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_min_relaxed(dst, val),
+        SeqCst => intrinsics::atomic_min(dst, val),
+        __Nonexhaustive => panic!("invalid memory ordering"),
+    }
+}
+
+/// returns the max value (signed comparison)
+#[inline]
+unsafe fn atomic_umax<T>(dst: *mut T, val: T, order: Ordering) -> T {
+    match order {
+        Acquire => intrinsics::atomic_umax_acq(dst, val),
+        Release => intrinsics::atomic_umax_rel(dst, val),
+        AcqRel => intrinsics::atomic_umax_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_umax_relaxed(dst, val),
+        SeqCst => intrinsics::atomic_umax(dst, val),
+        __Nonexhaustive => panic!("invalid memory ordering"),
+    }
+}
+
+/// returns the min value (signed comparison)
+#[inline]
+unsafe fn atomic_umin<T>(dst: *mut T, val: T, order: Ordering) -> T {
+    match order {
+        Acquire => intrinsics::atomic_umin_acq(dst, val),
+        Release => intrinsics::atomic_umin_rel(dst, val),
+        AcqRel => intrinsics::atomic_umin_acqrel(dst, val),
+        Relaxed => intrinsics::atomic_umin_relaxed(dst, val),
+        SeqCst => intrinsics::atomic_umin(dst, val),
+        __Nonexhaustive => panic!("invalid memory ordering"),
+    }
+}
+
 /// An atomic fence.
 ///
 /// Depending on the specified order, a fence prevents the compiler and CPU from
diff --git a/src/libcore/tests/ascii.rs b/src/libcore/tests/ascii.rs
index 4d43067ad2c..950222dbcfa 100644
--- a/src/libcore/tests/ascii.rs
+++ b/src/libcore/tests/ascii.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use core::char::from_u32;
-use std::ascii::AsciiExt;
 
 #[test]
 fn test_is_ascii() {
@@ -143,8 +142,6 @@ macro_rules! assert_all {
                            stringify!($what), b);
                 }
             }
-            assert!($str.$what());
-            assert!($str.as_bytes().$what());
         )+
     }};
     ($what:ident, $($str:tt),+,) => (assert_all!($what,$($str),+))
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index a962efadd64..2abac0cf1d5 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1147,6 +1147,33 @@ fn test_find() {
 }
 
 #[test]
+fn test_find_map() {
+    let xs: &[isize] = &[];
+    assert_eq!(xs.iter().find_map(half_if_even), None);
+    let xs: &[isize] = &[3, 5];
+    assert_eq!(xs.iter().find_map(half_if_even), None);
+    let xs: &[isize] = &[4, 5];
+    assert_eq!(xs.iter().find_map(half_if_even), Some(2));
+    let xs: &[isize] = &[3, 6];
+    assert_eq!(xs.iter().find_map(half_if_even), Some(3));
+
+    let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7];
+    let mut iter = xs.iter();
+    assert_eq!(iter.find_map(half_if_even), Some(1));
+    assert_eq!(iter.find_map(half_if_even), Some(2));
+    assert_eq!(iter.find_map(half_if_even), Some(3));
+    assert_eq!(iter.next(), Some(&7));
+
+    fn half_if_even(x: &isize) -> Option<isize> {
+        if x % 2 == 0 {
+            Some(x / 2)
+        } else {
+            None
+        }
+    }
+}
+
+#[test]
 fn test_position() {
     let v = &[1, 3, 9, 27, 103, 14, 11];
     assert_eq!(v.iter().position(|x| *x & 1 == 0).unwrap(), 5);
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index e9a8113ef10..de7211e718c 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -23,13 +23,10 @@
 #![feature(fmt_internals)]
 #![feature(hashmap_internals)]
 #![feature(iterator_step_by)]
-#![feature(i128_type)]
+#![cfg_attr(stage0, feature(i128_type))]
 #![cfg_attr(stage0, feature(inclusive_range_syntax))]
-#![feature(iterator_try_fold)]
 #![feature(iterator_flatten)]
-#![feature(conservative_impl_trait)]
-#![feature(iter_rfind)]
-#![feature(iter_rfold)]
+#![cfg_attr(stage0, feature(conservative_impl_trait))]
 #![feature(iterator_repeat_with)]
 #![feature(nonzero)]
 #![feature(pattern)]
@@ -43,12 +40,12 @@
 #![feature(step_trait)]
 #![feature(test)]
 #![feature(trusted_len)]
-#![feature(try_from)]
 #![feature(try_trait)]
 #![feature(exact_chunks)]
 #![feature(atomic_nand)]
 #![feature(reverse_bits)]
 #![feature(inclusive_range_fields)]
+#![feature(iterator_find_map)]
 
 extern crate core;
 extern crate test;
diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs
index a795dd57504..8d39298bac3 100644
--- a/src/libcore/tests/nonzero.rs
+++ b/src/libcore/tests/nonzero.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::nonzero::NonZero;
+use core::num::NonZeroU32;
 use core::option::Option;
 use core::option::Option::{Some, None};
 use std::mem::size_of;
@@ -16,28 +16,28 @@ use std::mem::size_of;
 #[test]
 fn test_create_nonzero_instance() {
     let _a = unsafe {
-        NonZero::new_unchecked(21)
+        NonZeroU32::new_unchecked(21)
     };
 }
 
 #[test]
 fn test_size_nonzero_in_option() {
-    assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>());
+    assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
 }
 
 #[test]
 fn test_match_on_nonzero_option() {
     let a = Some(unsafe {
-        NonZero::new_unchecked(42)
+        NonZeroU32::new_unchecked(42)
     });
     match a {
         Some(val) => assert_eq!(val.get(), 42),
-        None => panic!("unexpected None while matching on Some(NonZero(_))")
+        None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
     }
 
-    match unsafe { Some(NonZero::new_unchecked(43)) } {
+    match unsafe { Some(NonZeroU32::new_unchecked(43)) } {
         Some(val) => assert_eq!(val.get(), 43),
-        None => panic!("unexpected None while matching on Some(NonZero(_))")
+        None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
     }
 }
 
@@ -98,3 +98,26 @@ fn test_match_option_string() {
         None => panic!("unexpected None while matching on Some(String { ... })")
     }
 }
+
+mod atom {
+    use core::num::NonZeroU32;
+
+    #[derive(PartialEq, Eq)]
+    pub struct Atom {
+        index: NonZeroU32, // private
+    }
+    pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } };
+}
+
+macro_rules! atom {
+    ("foo") => { atom::FOO_ATOM }
+}
+
+#[test]
+fn test_match_nonzero_const_pattern() {
+    match atom!("foo") {
+        // Using as a pattern is supported by the compiler:
+        atom!("foo") => {}
+        _ => panic!("Expected the const item as a pattern to match.")
+    }
+}
diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs
index 587dcbe6d67..c7edb55b378 100644
--- a/src/libcore/tests/num/mod.rs
+++ b/src/libcore/tests/num/mod.rs
@@ -37,15 +37,6 @@ mod flt2dec;
 mod dec2flt;
 mod bignum;
 
-
-/// Adds the attribute to all items in the block.
-macro_rules! cfg_block {
-    ($(#[$attr:meta]{$($it:item)*})*) => {$($(
-        #[$attr]
-        $it
-    )*)*}
-}
-
 /// Groups items that assume the pointer width is either 16/32/64, and has to be altered if
 /// support for larger/smaller pointer widths are added in the future.
 macro_rules! assume_usize_width {
@@ -318,42 +309,6 @@ assume_usize_width! {
 
     test_impl_try_from_always_ok! { test_try_u16usize, u16, usize }
     test_impl_try_from_always_ok! { test_try_i16isize, i16, isize }
-
-    test_impl_try_from_always_ok! { test_try_usizeu64, usize, u64 }
-    test_impl_try_from_always_ok! { test_try_usizeu128, usize, u128 }
-    test_impl_try_from_always_ok! { test_try_usizei128, usize, i128 }
-
-    test_impl_try_from_always_ok! { test_try_isizei64, isize, i64 }
-    test_impl_try_from_always_ok! { test_try_isizei128, isize, i128 }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 }
-            test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 }
-            test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
-            test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 }
-            test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
-            test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
-            test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 }
-            test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 }
-            test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
-            test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
-            test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_always_ok! { test_try_u16isize, u16, isize }
-            test_impl_try_from_always_ok! { test_try_u32usize, u32, usize }
-            test_impl_try_from_always_ok! { test_try_u32isize, u32, isize }
-            test_impl_try_from_always_ok! { test_try_i32isize, i32, isize }
-            test_impl_try_from_always_ok! { test_try_u64usize, u64, usize }
-            test_impl_try_from_always_ok! { test_try_i64isize, i64, isize }
-        }
-    );
 }
 
 /// Conversions where max of $source can be represented as $target,
@@ -402,24 +357,6 @@ assume_usize_width! {
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu64, isize, u64 }
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu128, isize, u128 }
     test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeusize, isize, usize }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu16, isize, u16 }
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_isizeu32, isize, u32 }
-
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32usize, i32, usize }
-            test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64usize, i64, usize }
-        }
-    );
 }
 
 /// Conversions where max of $source can not be represented as $target,
@@ -461,29 +398,9 @@ test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i64, u128, i64 }
 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128i128, u128, i128 }
 
 assume_usize_width! {
-    test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64isize, u64, isize }
-    test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u128isize, u128, isize }
-
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei8, usize, i8 }
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei16, usize, i16 }
     test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizeisize, usize, isize }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize }
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize }
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei32, usize, i32 }
-            test_impl_try_from_unsigned_to_signed_upper_err! { test_try_usizei64, usize, i64 }
-        }
-    );
 }
 
 /// Conversions where min/max of $source can not be represented as $target.
@@ -543,34 +460,6 @@ test_impl_try_from_same_sign_err! { test_try_i128i64, i128, i64 }
 
 assume_usize_width! {
     test_impl_try_from_same_sign_err! { test_try_usizeu8, usize, u8 }
-    test_impl_try_from_same_sign_err! { test_try_u128usize, u128, usize }
-    test_impl_try_from_same_sign_err! { test_try_i128isize, i128, isize }
-
-    cfg_block!(
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_same_sign_err! { test_try_u32usize, u32, usize }
-            test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
-
-            test_impl_try_from_same_sign_err! { test_try_i32isize, i32, isize }
-            test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
-        }
-
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_same_sign_err! { test_try_u64usize, u64, usize }
-            test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
-
-            test_impl_try_from_same_sign_err! { test_try_i64isize, i64, isize }
-            test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
-        }
-
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_same_sign_err! { test_try_usizeu16, usize, u16 }
-            test_impl_try_from_same_sign_err! { test_try_usizeu32, usize, u32 }
-
-            test_impl_try_from_same_sign_err! { test_try_isizei16, isize, i16 }
-            test_impl_try_from_same_sign_err! { test_try_isizei32, isize, i32 }
-        }
-    );
 }
 
 /// Conversions where neither the min nor the max of $source can be represented by
@@ -615,22 +504,6 @@ test_impl_try_from_signed_to_unsigned_err! { test_try_i128u64, i128, u64 }
 assume_usize_width! {
     test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu8, isize, u8 }
     test_impl_try_from_signed_to_unsigned_err! { test_try_i128usize, i128, usize }
-
-    cfg_block! {
-        #[cfg(target_pointer_width = "16")] {
-            test_impl_try_from_signed_to_unsigned_err! { test_try_i32usize, i32, usize }
-            test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
-        }
-        #[cfg(target_pointer_width = "32")] {
-            test_impl_try_from_signed_to_unsigned_err! { test_try_i64usize, i64, usize }
-
-            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
-        }
-        #[cfg(target_pointer_width = "64")] {
-            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu16, isize, u16 }
-            test_impl_try_from_signed_to_unsigned_err! { test_try_isizeu32, isize, u32 }
-        }
-    }
 }
 
 macro_rules! test_float {