about summary refs log tree commit diff
path: root/library/core/src/ops
diff options
context:
space:
mode:
authormark <markm@cs.wisc.edu>2020-06-11 21:31:49 -0500
committermark <markm@cs.wisc.edu>2020-07-27 19:51:13 -0500
commit2c31b45ae878b821975c4ebd94cc1e49f6073fd0 (patch)
tree14f64e683e3f64dcbcfb8c2c7cb45ac7592e6e09 /library/core/src/ops
parent9be8ffcb0206fc1558069a7b4766090df7877659 (diff)
mv std libs to library/
Diffstat (limited to 'library/core/src/ops')
-rw-r--r--library/core/src/ops/arith.rs900
-rw-r--r--library/core/src/ops/bit.rs873
-rw-r--r--library/core/src/ops/deref.rs194
-rw-r--r--library/core/src/ops/drop.rs167
-rw-r--r--library/core/src/ops/function.rs289
-rw-r--r--library/core/src/ops/generator.rs134
-rw-r--r--library/core/src/ops/index.rs172
-rw-r--r--library/core/src/ops/mod.rs199
-rw-r--r--library/core/src/ops/range.rs885
-rw-r--r--library/core/src/ops/try.rs58
-rw-r--r--library/core/src/ops/unsize.rs101
11 files changed, 3972 insertions, 0 deletions
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
new file mode 100644
index 00000000000..622a138abe9
--- /dev/null
+++ b/library/core/src/ops/arith.rs
@@ -0,0 +1,900 @@
+/// The addition operator `+`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
+/// example, [`std::time::SystemTime`] implements `Add<Duration>`, which permits
+/// operations of the form `SystemTime = SystemTime + Duration`.
+///
+/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
+///
+/// # Examples
+///
+/// ## `Add`able points
+///
+/// ```
+/// use std::ops::Add;
+///
+/// #[derive(Debug, Copy, Clone, PartialEq)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
+///
+/// impl Add for Point {
+///     type Output = Self;
+///
+///     fn add(self, other: Self) -> Self {
+///         Self {
+///             x: self.x + other.x,
+///             y: self.y + other.y,
+///         }
+///     }
+/// }
+///
+/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
+///            Point { x: 3, y: 3 });
+/// ```
+///
+/// ## Implementing `Add` with generics
+///
+/// Here is an example of the same `Point` struct implementing the `Add` trait
+/// using generics.
+///
+/// ```
+/// use std::ops::Add;
+///
+/// #[derive(Debug, Copy, Clone, PartialEq)]
+/// struct Point<T> {
+///     x: T,
+///     y: T,
+/// }
+///
+/// // Notice that the implementation uses the associated type `Output`.
+/// impl<T: Add<Output = T>> Add for Point<T> {
+///     type Output = Self;
+///
+///     fn add(self, other: Self) -> Self::Output {
+///         Self {
+///             x: self.x + other.x,
+///             y: self.y + other.y,
+///         }
+///     }
+/// }
+///
+/// assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
+///            Point { x: 3, y: 3 });
+/// ```
+#[lang = "add"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
+    on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
+    message = "cannot add `{Rhs}` to `{Self}`",
+    label = "no implementation for `{Self} + {Rhs}`"
+)]
+#[doc(alias = "+")]
+pub trait Add<Rhs = Self> {
+    /// The resulting type after applying the `+` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `+` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn add(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! add_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Add for $t {
+            type Output = $t;
+
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn add(self, other: $t) -> $t { self + other }
+        }
+
+        forward_ref_binop! { impl Add, add for $t, $t }
+    )*)
+}
+
+add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The subtraction operator `-`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory. For
+/// example, [`std::time::SystemTime`] implements `Sub<Duration>`, which permits
+/// operations of the form `SystemTime = SystemTime - Duration`.
+///
+/// [`std::time::SystemTime`]: ../../std/time/struct.SystemTime.html
+///
+/// # Examples
+///
+/// ## `Sub`tractable points
+///
+/// ```
+/// use std::ops::Sub;
+///
+/// #[derive(Debug, Copy, Clone, PartialEq)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
+///
+/// impl Sub for Point {
+///     type Output = Point;
+///
+///     fn sub(self, other: Point) -> Point {
+///         Point {
+///             x: self.x - other.x,
+///             y: self.y - other.y,
+///         }
+///     }
+/// }
+///
+/// assert_eq!(Point { x: 3, y: 3 } - Point { x: 2, y: 3 },
+///            Point { x: 1, y: 0 });
+/// ```
+///
+/// ## Implementing `Sub` with generics
+///
+/// Here is an example of the same `Point` struct implementing the `Sub` trait
+/// using generics.
+///
+/// ```
+/// use std::ops::Sub;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Point<T> {
+///     x: T,
+///     y: T,
+/// }
+///
+/// // Notice that the implementation uses the associated type `Output`.
+/// impl<T: Sub<Output = T>> Sub for Point<T> {
+///     type Output = Self;
+///
+///     fn sub(self, other: Self) -> Self::Output {
+///         Point {
+///             x: self.x - other.x,
+///             y: self.y - other.y,
+///         }
+///     }
+/// }
+///
+/// assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
+///            Point { x: 1, y: 3 });
+/// ```
+#[lang = "sub"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "cannot subtract `{Rhs}` from `{Self}`",
+    label = "no implementation for `{Self} - {Rhs}`"
+)]
+#[doc(alias = "-")]
+pub trait Sub<Rhs = Self> {
+    /// The resulting type after applying the `-` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `-` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn sub(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! sub_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Sub for $t {
+            type Output = $t;
+
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn sub(self, other: $t) -> $t { self - other }
+        }
+
+        forward_ref_binop! { impl Sub, sub for $t, $t }
+    )*)
+}
+
+sub_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The multiplication operator `*`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
+///
+/// # Examples
+///
+/// ## `Mul`tipliable rational numbers
+///
+/// ```
+/// use std::ops::Mul;
+///
+/// // By the fundamental theorem of arithmetic, rational numbers in lowest
+/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
+/// // derive `Eq` and `PartialEq`.
+/// #[derive(Debug, Eq, PartialEq)]
+/// struct Rational {
+///     numerator: usize,
+///     denominator: usize,
+/// }
+///
+/// impl Rational {
+///     fn new(numerator: usize, denominator: usize) -> Self {
+///         if denominator == 0 {
+///             panic!("Zero is an invalid denominator!");
+///         }
+///
+///         // Reduce to lowest terms by dividing by the greatest common
+///         // divisor.
+///         let gcd = gcd(numerator, denominator);
+///         Rational {
+///             numerator: numerator / gcd,
+///             denominator: denominator / gcd,
+///         }
+///     }
+/// }
+///
+/// impl Mul for Rational {
+///     // The multiplication of rational numbers is a closed operation.
+///     type Output = Self;
+///
+///     fn mul(self, rhs: Self) -> Self {
+///         let numerator = self.numerator * rhs.numerator;
+///         let denominator = self.denominator * rhs.denominator;
+///         Rational::new(numerator, denominator)
+///     }
+/// }
+///
+/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
+/// // divisor.
+/// fn gcd(x: usize, y: usize) -> usize {
+///     let mut x = x;
+///     let mut y = y;
+///     while y != 0 {
+///         let t = y;
+///         y = x % y;
+///         x = t;
+///     }
+///     x
+/// }
+///
+/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
+/// assert_eq!(Rational::new(2, 3) * Rational::new(3, 4),
+///            Rational::new(1, 2));
+/// ```
+///
+/// ## Multiplying vectors by scalars as in linear algebra
+///
+/// ```
+/// use std::ops::Mul;
+///
+/// struct Scalar { value: usize }
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Vector { value: Vec<usize> }
+///
+/// impl Mul<Scalar> for Vector {
+///     type Output = Self;
+///
+///     fn mul(self, rhs: Scalar) -> Self::Output {
+///         Vector { value: self.value.iter().map(|v| v * rhs.value).collect() }
+///     }
+/// }
+///
+/// let vector = Vector { value: vec![2, 4, 6] };
+/// let scalar = Scalar { value: 3 };
+/// assert_eq!(vector * scalar, Vector { value: vec![6, 12, 18] });
+/// ```
+#[lang = "mul"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "cannot multiply `{Rhs}` to `{Self}`",
+    label = "no implementation for `{Self} * {Rhs}`"
+)]
+#[doc(alias = "*")]
+pub trait Mul<Rhs = Self> {
+    /// The resulting type after applying the `*` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `*` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn mul(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! mul_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Mul for $t {
+            type Output = $t;
+
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn mul(self, other: $t) -> $t { self * other }
+        }
+
+        forward_ref_binop! { impl Mul, mul for $t, $t }
+    )*)
+}
+
+mul_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The division operator `/`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
+///
+/// # Examples
+///
+/// ## `Div`idable rational numbers
+///
+/// ```
+/// use std::ops::Div;
+///
+/// // By the fundamental theorem of arithmetic, rational numbers in lowest
+/// // terms are unique. So, by keeping `Rational`s in reduced form, we can
+/// // derive `Eq` and `PartialEq`.
+/// #[derive(Debug, Eq, PartialEq)]
+/// struct Rational {
+///     numerator: usize,
+///     denominator: usize,
+/// }
+///
+/// impl Rational {
+///     fn new(numerator: usize, denominator: usize) -> Self {
+///         if denominator == 0 {
+///             panic!("Zero is an invalid denominator!");
+///         }
+///
+///         // Reduce to lowest terms by dividing by the greatest common
+///         // divisor.
+///         let gcd = gcd(numerator, denominator);
+///         Rational {
+///             numerator: numerator / gcd,
+///             denominator: denominator / gcd,
+///         }
+///     }
+/// }
+///
+/// impl Div for Rational {
+///     // The division of rational numbers is a closed operation.
+///     type Output = Self;
+///
+///     fn div(self, rhs: Self) -> Self::Output {
+///         if rhs.numerator == 0 {
+///             panic!("Cannot divide by zero-valued `Rational`!");
+///         }
+///
+///         let numerator = self.numerator * rhs.denominator;
+///         let denominator = self.denominator * rhs.numerator;
+///         Rational::new(numerator, denominator)
+///     }
+/// }
+///
+/// // Euclid's two-thousand-year-old algorithm for finding the greatest common
+/// // divisor.
+/// fn gcd(x: usize, y: usize) -> usize {
+///     let mut x = x;
+///     let mut y = y;
+///     while y != 0 {
+///         let t = y;
+///         y = x % y;
+///         x = t;
+///     }
+///     x
+/// }
+///
+/// assert_eq!(Rational::new(1, 2), Rational::new(2, 4));
+/// assert_eq!(Rational::new(1, 2) / Rational::new(3, 4),
+///            Rational::new(2, 3));
+/// ```
+///
+/// ## Dividing vectors by scalars as in linear algebra
+///
+/// ```
+/// use std::ops::Div;
+///
+/// struct Scalar { value: f32 }
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Vector { value: Vec<f32> }
+///
+/// impl Div<Scalar> for Vector {
+///     type Output = Self;
+///
+///     fn div(self, rhs: Scalar) -> Self::Output {
+///         Vector { value: self.value.iter().map(|v| v / rhs.value).collect() }
+///     }
+/// }
+///
+/// let scalar = Scalar { value: 2f32 };
+/// let vector = Vector { value: vec![2f32, 4f32, 6f32] };
+/// assert_eq!(vector / scalar, Vector { value: vec![1f32, 2f32, 3f32] });
+/// ```
+#[lang = "div"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "cannot divide `{Self}` by `{Rhs}`",
+    label = "no implementation for `{Self} / {Rhs}`"
+)]
+#[doc(alias = "/")]
+pub trait Div<Rhs = Self> {
+    /// The resulting type after applying the `/` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `/` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn div(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! div_impl_integer {
+    ($($t:ty)*) => ($(
+        /// This operation rounds towards zero, truncating any
+        /// fractional part of the exact result.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Div for $t {
+            type Output = $t;
+
+            #[inline]
+            fn div(self, other: $t) -> $t { self / other }
+        }
+
+        forward_ref_binop! { impl Div, div for $t, $t }
+    )*)
+}
+
+div_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+macro_rules! div_impl_float {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Div for $t {
+            type Output = $t;
+
+            #[inline]
+            fn div(self, other: $t) -> $t { self / other }
+        }
+
+        forward_ref_binop! { impl Div, div for $t, $t }
+    )*)
+}
+
+div_impl_float! { f32 f64 }
+
+/// The remainder operator `%`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
+///
+/// # Examples
+///
+/// This example implements `Rem` on a `SplitSlice` object. After `Rem` is
+/// implemented, one can use the `%` operator to find out what the remaining
+/// elements of the slice would be after splitting it into equal slices of a
+/// given length.
+///
+/// ```
+/// use std::ops::Rem;
+///
+/// #[derive(PartialEq, Debug)]
+/// struct SplitSlice<'a, T: 'a> {
+///     slice: &'a [T],
+/// }
+///
+/// impl<'a, T> Rem<usize> for SplitSlice<'a, T> {
+///     type Output = Self;
+///
+///     fn rem(self, modulus: usize) -> Self::Output {
+///         let len = self.slice.len();
+///         let rem = len % modulus;
+///         let start = len - rem;
+///         SplitSlice {slice: &self.slice[start..]}
+///     }
+/// }
+///
+/// // If we were to divide &[0, 1, 2, 3, 4, 5, 6, 7] into slices of size 3,
+/// // the remainder would be &[6, 7].
+/// assert_eq!(SplitSlice { slice: &[0, 1, 2, 3, 4, 5, 6, 7] } % 3,
+///            SplitSlice { slice: &[6, 7] });
+/// ```
+#[lang = "rem"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "cannot mod `{Self}` by `{Rhs}`",
+    label = "no implementation for `{Self} % {Rhs}`"
+)]
+#[doc(alias = "%")]
+pub trait Rem<Rhs = Self> {
+    /// The resulting type after applying the `%` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `%` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn rem(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! rem_impl_integer {
+    ($($t:ty)*) => ($(
+        /// This operation satisfies `n % d == n - (n / d) * d`. The
+        /// result has the same sign as the left operand.
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Rem for $t {
+            type Output = $t;
+
+            #[inline]
+            fn rem(self, other: $t) -> $t { self % other }
+        }
+
+        forward_ref_binop! { impl Rem, rem for $t, $t }
+    )*)
+}
+
+rem_impl_integer! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+macro_rules! rem_impl_float {
+    ($($t:ty)*) => ($(
+
+        /// The remainder from the division of two floats.
+        ///
+        /// The remainder has the same sign as the dividend and is computed as:
+        /// `x - (x / y).trunc() * y`.
+        ///
+        /// # Examples
+        /// ```
+        /// let x: f32 = 50.50;
+        /// let y: f32 = 8.125;
+        /// let remainder = x - (x / y).trunc() * y;
+        ///
+        /// // The answer to both operations is 1.75
+        /// assert_eq!(x % y, remainder);
+        /// ```
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Rem for $t {
+            type Output = $t;
+
+            #[inline]
+            fn rem(self, other: $t) -> $t { self % other }
+        }
+
+        forward_ref_binop! { impl Rem, rem for $t, $t }
+    )*)
+}
+
+rem_impl_float! { f32 f64 }
+
+/// The unary negation operator `-`.
+///
+/// # Examples
+///
+/// An implementation of `Neg` for `Sign`, which allows the use of `-` to
+/// negate its value.
+///
+/// ```
+/// use std::ops::Neg;
+///
+/// #[derive(Debug, PartialEq)]
+/// enum Sign {
+///     Negative,
+///     Zero,
+///     Positive,
+/// }
+///
+/// impl Neg for Sign {
+///     type Output = Sign;
+///
+///     fn neg(self) -> Self::Output {
+///         match self {
+///             Sign::Negative => Sign::Positive,
+///             Sign::Zero => Sign::Zero,
+///             Sign::Positive => Sign::Negative,
+///         }
+///     }
+/// }
+///
+/// // A negative positive is a negative.
+/// assert_eq!(-Sign::Positive, Sign::Negative);
+/// // A double negative is a positive.
+/// assert_eq!(-Sign::Negative, Sign::Positive);
+/// // Zero is its own negation.
+/// assert_eq!(-Sign::Zero, Sign::Zero);
+/// ```
+#[lang = "neg"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(alias = "-")]
+pub trait Neg {
+    /// The resulting type after applying the `-` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the unary `-` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn neg(self) -> Self::Output;
+}
+
+macro_rules! neg_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Neg for $t {
+            type Output = $t;
+
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn neg(self) -> $t { -self }
+        }
+
+        forward_ref_unop! { impl Neg, neg for $t }
+    )*)
+}
+
+neg_impl! { isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The addition assignment operator `+=`.
+///
+/// # Examples
+///
+/// This example creates a `Point` struct that implements the `AddAssign`
+/// trait, and then demonstrates add-assigning to a mutable `Point`.
+///
+/// ```
+/// use std::ops::AddAssign;
+///
+/// #[derive(Debug, Copy, Clone, PartialEq)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
+///
+/// impl AddAssign for Point {
+///     fn add_assign(&mut self, other: Self) {
+///         *self = Self {
+///             x: self.x + other.x,
+///             y: self.y + other.y,
+///         };
+///     }
+/// }
+///
+/// let mut point = Point { x: 1, y: 0 };
+/// point += Point { x: 2, y: 3 };
+/// assert_eq!(point, Point { x: 3, y: 3 });
+/// ```
+#[lang = "add_assign"]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "cannot add-assign `{Rhs}` to `{Self}`",
+    label = "no implementation for `{Self} += {Rhs}`"
+)]
+#[doc(alias = "+")]
+#[doc(alias = "+=")]
+pub trait AddAssign<Rhs = Self> {
+    /// Performs the `+=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn add_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! add_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl AddAssign for $t {
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn add_assign(&mut self, other: $t) { *self += other }
+        }
+
+        forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
+    )+)
+}
+
+add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The subtraction assignment operator `-=`.
+///
+/// # Examples
+///
+/// This example creates a `Point` struct that implements the `SubAssign`
+/// trait, and then demonstrates sub-assigning to a mutable `Point`.
+///
+/// ```
+/// use std::ops::SubAssign;
+///
+/// #[derive(Debug, Copy, Clone, PartialEq)]
+/// struct Point {
+///     x: i32,
+///     y: i32,
+/// }
+///
+/// impl SubAssign for Point {
+///     fn sub_assign(&mut self, other: Self) {
+///         *self = Self {
+///             x: self.x - other.x,
+///             y: self.y - other.y,
+///         };
+///     }
+/// }
+///
+/// let mut point = Point { x: 3, y: 3 };
+/// point -= Point { x: 2, y: 3 };
+/// assert_eq!(point, Point {x: 1, y: 0});
+/// ```
+#[lang = "sub_assign"]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "cannot subtract-assign `{Rhs}` from `{Self}`",
+    label = "no implementation for `{Self} -= {Rhs}`"
+)]
+#[doc(alias = "-")]
+#[doc(alias = "-=")]
+pub trait SubAssign<Rhs = Self> {
+    /// Performs the `-=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn sub_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! sub_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl SubAssign for $t {
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn sub_assign(&mut self, other: $t) { *self -= other }
+        }
+
+        forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
+    )+)
+}
+
+sub_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The multiplication assignment operator `*=`.
+///
+/// # Examples
+///
+/// ```
+/// use std::ops::MulAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Frequency { hertz: f64 }
+///
+/// impl MulAssign<f64> for Frequency {
+///     fn mul_assign(&mut self, rhs: f64) {
+///         self.hertz *= rhs;
+///     }
+/// }
+///
+/// let mut frequency = Frequency { hertz: 50.0 };
+/// frequency *= 4.0;
+/// assert_eq!(Frequency { hertz: 200.0 }, frequency);
+/// ```
+#[lang = "mul_assign"]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "cannot multiply-assign `{Rhs}` to `{Self}`",
+    label = "no implementation for `{Self} *= {Rhs}`"
+)]
+#[doc(alias = "*")]
+#[doc(alias = "*=")]
+pub trait MulAssign<Rhs = Self> {
+    /// Performs the `*=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn mul_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! mul_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl MulAssign for $t {
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn mul_assign(&mut self, other: $t) { *self *= other }
+        }
+
+        forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
+    )+)
+}
+
+mul_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The division assignment operator `/=`.
+///
+/// # Examples
+///
+/// ```
+/// use std::ops::DivAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Frequency { hertz: f64 }
+///
+/// impl DivAssign<f64> for Frequency {
+///     fn div_assign(&mut self, rhs: f64) {
+///         self.hertz /= rhs;
+///     }
+/// }
+///
+/// let mut frequency = Frequency { hertz: 200.0 };
+/// frequency /= 4.0;
+/// assert_eq!(Frequency { hertz: 50.0 }, frequency);
+/// ```
+#[lang = "div_assign"]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "cannot divide-assign `{Self}` by `{Rhs}`",
+    label = "no implementation for `{Self} /= {Rhs}`"
+)]
+#[doc(alias = "/")]
+#[doc(alias = "/=")]
+pub trait DivAssign<Rhs = Self> {
+    /// Performs the `/=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn div_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! div_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl DivAssign for $t {
+            #[inline]
+            fn div_assign(&mut self, other: $t) { *self /= other }
+        }
+
+        forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
+    )+)
+}
+
+div_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
+
+/// The remainder assignment operator `%=`.
+///
+/// # Examples
+///
+/// ```
+/// use std::ops::RemAssign;
+///
+/// struct CookieJar { cookies: u32 }
+///
+/// impl RemAssign<u32> for CookieJar {
+///     fn rem_assign(&mut self, piles: u32) {
+///         self.cookies %= piles;
+///     }
+/// }
+///
+/// let mut jar = CookieJar { cookies: 31 };
+/// let piles = 4;
+///
+/// println!("Splitting up {} cookies into {} even piles!", jar.cookies, piles);
+///
+/// jar %= piles;
+///
+/// println!("{} cookies remain in the cookie jar!", jar.cookies);
+/// ```
+#[lang = "rem_assign"]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "cannot mod-assign `{Self}` by `{Rhs}``",
+    label = "no implementation for `{Self} %= {Rhs}`"
+)]
+#[doc(alias = "%")]
+#[doc(alias = "%=")]
+pub trait RemAssign<Rhs = Self> {
+    /// Performs the `%=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn rem_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! rem_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl RemAssign for $t {
+            #[inline]
+            fn rem_assign(&mut self, other: $t) { *self %= other }
+        }
+
+        forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
+    )+)
+}
+
+rem_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs
new file mode 100644
index 00000000000..bcfff4a223b
--- /dev/null
+++ b/library/core/src/ops/bit.rs
@@ -0,0 +1,873 @@
+/// The unary logical negation operator `!`.
+///
+/// # Examples
+///
+/// An implementation of `Not` for `Answer`, which enables the use of `!` to
+/// invert its value.
+///
+/// ```
+/// use std::ops::Not;
+///
+/// #[derive(Debug, PartialEq)]
+/// enum Answer {
+///     Yes,
+///     No,
+/// }
+///
+/// impl Not for Answer {
+///     type Output = Answer;
+///
+///     fn not(self) -> Self::Output {
+///         match self {
+///             Answer::Yes => Answer::No,
+///             Answer::No => Answer::Yes
+///         }
+///     }
+/// }
+///
+/// assert_eq!(!Answer::Yes, Answer::No);
+/// assert_eq!(!Answer::No, Answer::Yes);
+/// ```
+#[lang = "not"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Not {
+    /// The resulting type after applying the `!` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the unary `!` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn not(self) -> Self::Output;
+}
+
+macro_rules! not_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Not for $t {
+            type Output = $t;
+
+            #[inline]
+            fn not(self) -> $t { !self }
+        }
+
+        forward_ref_unop! { impl Not, not for $t }
+    )*)
+}
+
+not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The bitwise AND operator `&`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
+///
+/// # Examples
+///
+/// An implementation of `BitAnd` for a wrapper around `bool`.
+///
+/// ```
+/// use std::ops::BitAnd;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Scalar(bool);
+///
+/// impl BitAnd for Scalar {
+///     type Output = Self;
+///
+///     // rhs is the "right-hand side" of the expression `a & b`
+///     fn bitand(self, rhs: Self) -> Self::Output {
+///         Scalar(self.0 & rhs.0)
+///     }
+/// }
+///
+/// assert_eq!(Scalar(true) & Scalar(true), Scalar(true));
+/// assert_eq!(Scalar(true) & Scalar(false), Scalar(false));
+/// assert_eq!(Scalar(false) & Scalar(true), Scalar(false));
+/// assert_eq!(Scalar(false) & Scalar(false), Scalar(false));
+/// ```
+///
+/// An implementation of `BitAnd` for a wrapper around `Vec<bool>`.
+///
+/// ```
+/// use std::ops::BitAnd;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct BooleanVector(Vec<bool>);
+///
+/// impl BitAnd for BooleanVector {
+///     type Output = Self;
+///
+///     fn bitand(self, BooleanVector(rhs): Self) -> Self::Output {
+///         let BooleanVector(lhs) = self;
+///         assert_eq!(lhs.len(), rhs.len());
+///         BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x && *y).collect())
+///     }
+/// }
+///
+/// let bv1 = BooleanVector(vec![true, true, false, false]);
+/// let bv2 = BooleanVector(vec![true, false, true, false]);
+/// let expected = BooleanVector(vec![true, false, false, false]);
+/// assert_eq!(bv1 & bv2, expected);
+/// ```
+#[lang = "bitand"]
+#[doc(alias = "&")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} & {Rhs}`",
+    label = "no implementation for `{Self} & {Rhs}`"
+)]
+pub trait BitAnd<Rhs = Self> {
+    /// The resulting type after applying the `&` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `&` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn bitand(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! bitand_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl BitAnd for $t {
+            type Output = $t;
+
+            #[inline]
+            fn bitand(self, rhs: $t) -> $t { self & rhs }
+        }
+
+        forward_ref_binop! { impl BitAnd, bitand for $t, $t }
+    )*)
+}
+
+bitand_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The bitwise OR operator `|`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
+///
+/// # Examples
+///
+/// An implementation of `BitOr` for a wrapper around `bool`.
+///
+/// ```
+/// use std::ops::BitOr;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Scalar(bool);
+///
+/// impl BitOr for Scalar {
+///     type Output = Self;
+///
+///     // rhs is the "right-hand side" of the expression `a | b`
+///     fn bitor(self, rhs: Self) -> Self {
+///         Scalar(self.0 | rhs.0)
+///     }
+/// }
+///
+/// assert_eq!(Scalar(true) | Scalar(true), Scalar(true));
+/// assert_eq!(Scalar(true) | Scalar(false), Scalar(true));
+/// assert_eq!(Scalar(false) | Scalar(true), Scalar(true));
+/// assert_eq!(Scalar(false) | Scalar(false), Scalar(false));
+/// ```
+///
+/// An implementation of `BitOr` for a wrapper around `Vec<bool>`.
+///
+/// ```
+/// use std::ops::BitOr;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct BooleanVector(Vec<bool>);
+///
+/// impl BitOr for BooleanVector {
+///     type Output = Self;
+///
+///     fn bitor(self, BooleanVector(rhs): Self) -> Self::Output {
+///         let BooleanVector(lhs) = self;
+///         assert_eq!(lhs.len(), rhs.len());
+///         BooleanVector(lhs.iter().zip(rhs.iter()).map(|(x, y)| *x || *y).collect())
+///     }
+/// }
+///
+/// let bv1 = BooleanVector(vec![true, true, false, false]);
+/// let bv2 = BooleanVector(vec![true, false, true, false]);
+/// let expected = BooleanVector(vec![true, true, true, false]);
+/// assert_eq!(bv1 | bv2, expected);
+/// ```
+#[lang = "bitor"]
+#[doc(alias = "|")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} | {Rhs}`",
+    label = "no implementation for `{Self} | {Rhs}`"
+)]
+pub trait BitOr<Rhs = Self> {
+    /// The resulting type after applying the `|` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `|` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn bitor(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! bitor_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl BitOr for $t {
+            type Output = $t;
+
+            #[inline]
+            fn bitor(self, rhs: $t) -> $t { self | rhs }
+        }
+
+        forward_ref_binop! { impl BitOr, bitor for $t, $t }
+    )*)
+}
+
+bitor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The bitwise XOR operator `^`.
+///
+/// Note that `Rhs` is `Self` by default, but this is not mandatory.
+///
+/// # Examples
+///
+/// An implementation of `BitXor` that lifts `^` to a wrapper around `bool`.
+///
+/// ```
+/// use std::ops::BitXor;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Scalar(bool);
+///
+/// impl BitXor for Scalar {
+///     type Output = Self;
+///
+///     // rhs is the "right-hand side" of the expression `a ^ b`
+///     fn bitxor(self, rhs: Self) -> Self::Output {
+///         Scalar(self.0 ^ rhs.0)
+///     }
+/// }
+///
+/// assert_eq!(Scalar(true) ^ Scalar(true), Scalar(false));
+/// assert_eq!(Scalar(true) ^ Scalar(false), Scalar(true));
+/// assert_eq!(Scalar(false) ^ Scalar(true), Scalar(true));
+/// assert_eq!(Scalar(false) ^ Scalar(false), Scalar(false));
+/// ```
+///
+/// An implementation of `BitXor` trait for a wrapper around `Vec<bool>`.
+///
+/// ```
+/// use std::ops::BitXor;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct BooleanVector(Vec<bool>);
+///
+/// impl BitXor for BooleanVector {
+///     type Output = Self;
+///
+///     fn bitxor(self, BooleanVector(rhs): Self) -> Self::Output {
+///         let BooleanVector(lhs) = self;
+///         assert_eq!(lhs.len(), rhs.len());
+///         BooleanVector(lhs.iter()
+///                          .zip(rhs.iter())
+///                          .map(|(x, y)| (*x || *y) && !(*x && *y))
+///                          .collect())
+///     }
+/// }
+///
+/// let bv1 = BooleanVector(vec![true, true, false, false]);
+/// let bv2 = BooleanVector(vec![true, false, true, false]);
+/// let expected = BooleanVector(vec![false, true, true, false]);
+/// assert_eq!(bv1 ^ bv2, expected);
+/// ```
+#[lang = "bitxor"]
+#[doc(alias = "^")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} ^ {Rhs}`",
+    label = "no implementation for `{Self} ^ {Rhs}`"
+)]
+pub trait BitXor<Rhs = Self> {
+    /// The resulting type after applying the `^` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `^` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn bitxor(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! bitxor_impl {
+    ($($t:ty)*) => ($(
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl BitXor for $t {
+            type Output = $t;
+
+            #[inline]
+            fn bitxor(self, other: $t) -> $t { self ^ other }
+        }
+
+        forward_ref_binop! { impl BitXor, bitxor for $t, $t }
+    )*)
+}
+
+bitxor_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The left shift operator `<<`. Note that because this trait is implemented
+/// for all integer types with multiple right-hand-side types, Rust's type
+/// checker has special handling for `_ << _`, setting the result type for
+/// integer operations to the type of the left-hand-side operand. This means
+/// that though `a << b` and `a.shl(b)` are one and the same from an evaluation
+/// standpoint, they are different when it comes to type inference.
+///
+/// # Examples
+///
+/// An implementation of `Shl` that lifts the `<<` operation on integers to a
+/// wrapper around `usize`.
+///
+/// ```
+/// use std::ops::Shl;
+///
+/// #[derive(PartialEq, Debug)]
+/// struct Scalar(usize);
+///
+/// impl Shl<Scalar> for Scalar {
+///     type Output = Self;
+///
+///     fn shl(self, Scalar(rhs): Self) -> Scalar {
+///         let Scalar(lhs) = self;
+///         Scalar(lhs << rhs)
+///     }
+/// }
+///
+/// assert_eq!(Scalar(4) << Scalar(2), Scalar(16));
+/// ```
+///
+/// An implementation of `Shl` that spins a vector leftward by a given amount.
+///
+/// ```
+/// use std::ops::Shl;
+///
+/// #[derive(PartialEq, Debug)]
+/// struct SpinVector<T: Clone> {
+///     vec: Vec<T>,
+/// }
+///
+/// impl<T: Clone> Shl<usize> for SpinVector<T> {
+///     type Output = Self;
+///
+///     fn shl(self, rhs: usize) -> Self::Output {
+///         // Rotate the vector by `rhs` places.
+///         let (a, b) = self.vec.split_at(rhs);
+///         let mut spun_vector: Vec<T> = vec![];
+///         spun_vector.extend_from_slice(b);
+///         spun_vector.extend_from_slice(a);
+///         SpinVector { vec: spun_vector }
+///     }
+/// }
+///
+/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } << 2,
+///            SpinVector { vec: vec![2, 3, 4, 0, 1] });
+/// ```
+#[lang = "shl"]
+#[doc(alias = "<<")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} << {Rhs}`",
+    label = "no implementation for `{Self} << {Rhs}`"
+)]
+pub trait Shl<Rhs = Self> {
+    /// The resulting type after applying the `<<` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `<<` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn shl(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! shl_impl {
+    ($t:ty, $f:ty) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Shl<$f> for $t {
+            type Output = $t;
+
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn shl(self, other: $f) -> $t {
+                self << other
+            }
+        }
+
+        forward_ref_binop! { impl Shl, shl for $t, $f }
+    };
+}
+
+macro_rules! shl_impl_all {
+    ($($t:ty)*) => ($(
+        shl_impl! { $t, u8 }
+        shl_impl! { $t, u16 }
+        shl_impl! { $t, u32 }
+        shl_impl! { $t, u64 }
+        shl_impl! { $t, u128 }
+        shl_impl! { $t, usize }
+
+        shl_impl! { $t, i8 }
+        shl_impl! { $t, i16 }
+        shl_impl! { $t, i32 }
+        shl_impl! { $t, i64 }
+        shl_impl! { $t, i128 }
+        shl_impl! { $t, isize }
+    )*)
+}
+
+shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
+
+/// The right shift operator `>>`. Note that because this trait is implemented
+/// for all integer types with multiple right-hand-side types, Rust's type
+/// checker has special handling for `_ >> _`, setting the result type for
+/// integer operations to the type of the left-hand-side operand. This means
+/// that though `a >> b` and `a.shr(b)` are one and the same from an evaluation
+/// standpoint, they are different when it comes to type inference.
+///
+/// # Examples
+///
+/// An implementation of `Shr` that lifts the `>>` operation on integers to a
+/// wrapper around `usize`.
+///
+/// ```
+/// use std::ops::Shr;
+///
+/// #[derive(PartialEq, Debug)]
+/// struct Scalar(usize);
+///
+/// impl Shr<Scalar> for Scalar {
+///     type Output = Self;
+///
+///     fn shr(self, Scalar(rhs): Self) -> Scalar {
+///         let Scalar(lhs) = self;
+///         Scalar(lhs >> rhs)
+///     }
+/// }
+///
+/// assert_eq!(Scalar(16) >> Scalar(2), Scalar(4));
+/// ```
+///
+/// An implementation of `Shr` that spins a vector rightward by a given amount.
+///
+/// ```
+/// use std::ops::Shr;
+///
+/// #[derive(PartialEq, Debug)]
+/// struct SpinVector<T: Clone> {
+///     vec: Vec<T>,
+/// }
+///
+/// impl<T: Clone> Shr<usize> for SpinVector<T> {
+///     type Output = Self;
+///
+///     fn shr(self, rhs: usize) -> Self::Output {
+///         // Rotate the vector by `rhs` places.
+///         let (a, b) = self.vec.split_at(self.vec.len() - rhs);
+///         let mut spun_vector: Vec<T> = vec![];
+///         spun_vector.extend_from_slice(b);
+///         spun_vector.extend_from_slice(a);
+///         SpinVector { vec: spun_vector }
+///     }
+/// }
+///
+/// assert_eq!(SpinVector { vec: vec![0, 1, 2, 3, 4] } >> 2,
+///            SpinVector { vec: vec![3, 4, 0, 1, 2] });
+/// ```
+#[lang = "shr"]
+#[doc(alias = ">>")]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} >> {Rhs}`",
+    label = "no implementation for `{Self} >> {Rhs}`"
+)]
+pub trait Shr<Rhs = Self> {
+    /// The resulting type after applying the `>>` operator.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output;
+
+    /// Performs the `>>` operation.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn shr(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! shr_impl {
+    ($t:ty, $f:ty) => {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        impl Shr<$f> for $t {
+            type Output = $t;
+
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn shr(self, other: $f) -> $t {
+                self >> other
+            }
+        }
+
+        forward_ref_binop! { impl Shr, shr for $t, $f }
+    };
+}
+
+macro_rules! shr_impl_all {
+    ($($t:ty)*) => ($(
+        shr_impl! { $t, u8 }
+        shr_impl! { $t, u16 }
+        shr_impl! { $t, u32 }
+        shr_impl! { $t, u64 }
+        shr_impl! { $t, u128 }
+        shr_impl! { $t, usize }
+
+        shr_impl! { $t, i8 }
+        shr_impl! { $t, i16 }
+        shr_impl! { $t, i32 }
+        shr_impl! { $t, i64 }
+        shr_impl! { $t, i128 }
+        shr_impl! { $t, isize }
+    )*)
+}
+
+shr_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
+
+/// The bitwise AND assignment operator `&=`.
+///
+/// # Examples
+///
+/// An implementation of `BitAndAssign` that lifts the `&=` operator to a
+/// wrapper around `bool`.
+///
+/// ```
+/// use std::ops::BitAndAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Scalar(bool);
+///
+/// impl BitAndAssign for Scalar {
+///     // rhs is the "right-hand side" of the expression `a &= b`
+///     fn bitand_assign(&mut self, rhs: Self) {
+///         *self = Scalar(self.0 & rhs.0)
+///     }
+/// }
+///
+/// let mut scalar = Scalar(true);
+/// scalar &= Scalar(true);
+/// assert_eq!(scalar, Scalar(true));
+///
+/// let mut scalar = Scalar(true);
+/// scalar &= Scalar(false);
+/// assert_eq!(scalar, Scalar(false));
+///
+/// let mut scalar = Scalar(false);
+/// scalar &= Scalar(true);
+/// assert_eq!(scalar, Scalar(false));
+///
+/// let mut scalar = Scalar(false);
+/// scalar &= Scalar(false);
+/// assert_eq!(scalar, Scalar(false));
+/// ```
+///
+/// Here, the `BitAndAssign` trait is implemented for a wrapper around
+/// `Vec<bool>`.
+///
+/// ```
+/// use std::ops::BitAndAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct BooleanVector(Vec<bool>);
+///
+/// impl BitAndAssign for BooleanVector {
+///     // `rhs` is the "right-hand side" of the expression `a &= b`.
+///     fn bitand_assign(&mut self, rhs: Self) {
+///         assert_eq!(self.0.len(), rhs.0.len());
+///         *self = BooleanVector(self.0
+///                                   .iter()
+///                                   .zip(rhs.0.iter())
+///                                   .map(|(x, y)| *x && *y)
+///                                   .collect());
+///     }
+/// }
+///
+/// let mut bv = BooleanVector(vec![true, true, false, false]);
+/// bv &= BooleanVector(vec![true, false, true, false]);
+/// let expected = BooleanVector(vec![true, false, false, false]);
+/// assert_eq!(bv, expected);
+/// ```
+#[lang = "bitand_assign"]
+#[doc(alias = "&=")]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} &= {Rhs}`",
+    label = "no implementation for `{Self} &= {Rhs}`"
+)]
+pub trait BitAndAssign<Rhs = Self> {
+    /// Performs the `&=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn bitand_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! bitand_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl BitAndAssign for $t {
+            #[inline]
+            fn bitand_assign(&mut self, other: $t) { *self &= other }
+        }
+
+        forward_ref_op_assign! { impl BitAndAssign, bitand_assign for $t, $t }
+    )+)
+}
+
+bitand_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The bitwise OR assignment operator `|=`.
+///
+/// # Examples
+///
+/// ```
+/// use std::ops::BitOrAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct PersonalPreferences {
+///     likes_cats: bool,
+///     likes_dogs: bool,
+/// }
+///
+/// impl BitOrAssign for PersonalPreferences {
+///     fn bitor_assign(&mut self, rhs: Self) {
+///         self.likes_cats |= rhs.likes_cats;
+///         self.likes_dogs |= rhs.likes_dogs;
+///     }
+/// }
+///
+/// let mut prefs = PersonalPreferences { likes_cats: true, likes_dogs: false };
+/// prefs |= PersonalPreferences { likes_cats: false, likes_dogs: true };
+/// assert_eq!(prefs, PersonalPreferences { likes_cats: true, likes_dogs: true });
+/// ```
+#[lang = "bitor_assign"]
+#[doc(alias = "|=")]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} |= {Rhs}`",
+    label = "no implementation for `{Self} |= {Rhs}`"
+)]
+pub trait BitOrAssign<Rhs = Self> {
+    /// Performs the `|=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn bitor_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! bitor_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl BitOrAssign for $t {
+            #[inline]
+            fn bitor_assign(&mut self, other: $t) { *self |= other }
+        }
+
+        forward_ref_op_assign! { impl BitOrAssign, bitor_assign for $t, $t }
+    )+)
+}
+
+bitor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The bitwise XOR assignment operator `^=`.
+///
+/// # Examples
+///
+/// ```
+/// use std::ops::BitXorAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Personality {
+///     has_soul: bool,
+///     likes_knitting: bool,
+/// }
+///
+/// impl BitXorAssign for Personality {
+///     fn bitxor_assign(&mut self, rhs: Self) {
+///         self.has_soul ^= rhs.has_soul;
+///         self.likes_knitting ^= rhs.likes_knitting;
+///     }
+/// }
+///
+/// let mut personality = Personality { has_soul: false, likes_knitting: true };
+/// personality ^= Personality { has_soul: true, likes_knitting: true };
+/// assert_eq!(personality, Personality { has_soul: true, likes_knitting: false});
+/// ```
+#[lang = "bitxor_assign"]
+#[doc(alias = "^=")]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} ^= {Rhs}`",
+    label = "no implementation for `{Self} ^= {Rhs}`"
+)]
+pub trait BitXorAssign<Rhs = Self> {
+    /// Performs the `^=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn bitxor_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! bitxor_assign_impl {
+    ($($t:ty)+) => ($(
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl BitXorAssign for $t {
+            #[inline]
+            fn bitxor_assign(&mut self, other: $t) { *self ^= other }
+        }
+
+        forward_ref_op_assign! { impl BitXorAssign, bitxor_assign for $t, $t }
+    )+)
+}
+
+bitxor_assign_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+/// The left shift assignment operator `<<=`.
+///
+/// # Examples
+///
+/// An implementation of `ShlAssign` for a wrapper around `usize`.
+///
+/// ```
+/// use std::ops::ShlAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Scalar(usize);
+///
+/// impl ShlAssign<usize> for Scalar {
+///     fn shl_assign(&mut self, rhs: usize) {
+///         self.0 <<= rhs;
+///     }
+/// }
+///
+/// let mut scalar = Scalar(4);
+/// scalar <<= 2;
+/// assert_eq!(scalar, Scalar(16));
+/// ```
+#[lang = "shl_assign"]
+#[doc(alias = "<<=")]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} <<= {Rhs}`",
+    label = "no implementation for `{Self} <<= {Rhs}`"
+)]
+pub trait ShlAssign<Rhs = Self> {
+    /// Performs the `<<=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn shl_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! shl_assign_impl {
+    ($t:ty, $f:ty) => {
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl ShlAssign<$f> for $t {
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn shl_assign(&mut self, other: $f) {
+                *self <<= other
+            }
+        }
+
+        forward_ref_op_assign! { impl ShlAssign, shl_assign for $t, $f }
+    };
+}
+
+macro_rules! shl_assign_impl_all {
+    ($($t:ty)*) => ($(
+        shl_assign_impl! { $t, u8 }
+        shl_assign_impl! { $t, u16 }
+        shl_assign_impl! { $t, u32 }
+        shl_assign_impl! { $t, u64 }
+        shl_assign_impl! { $t, u128 }
+        shl_assign_impl! { $t, usize }
+
+        shl_assign_impl! { $t, i8 }
+        shl_assign_impl! { $t, i16 }
+        shl_assign_impl! { $t, i32 }
+        shl_assign_impl! { $t, i64 }
+        shl_assign_impl! { $t, i128 }
+        shl_assign_impl! { $t, isize }
+    )*)
+}
+
+shl_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
+
+/// The right shift assignment operator `>>=`.
+///
+/// # Examples
+///
+/// An implementation of `ShrAssign` for a wrapper around `usize`.
+///
+/// ```
+/// use std::ops::ShrAssign;
+///
+/// #[derive(Debug, PartialEq)]
+/// struct Scalar(usize);
+///
+/// impl ShrAssign<usize> for Scalar {
+///     fn shr_assign(&mut self, rhs: usize) {
+///         self.0 >>= rhs;
+///     }
+/// }
+///
+/// let mut scalar = Scalar(16);
+/// scalar >>= 2;
+/// assert_eq!(scalar, Scalar(4));
+/// ```
+#[lang = "shr_assign"]
+#[doc(alias = ">>=")]
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+#[rustc_on_unimplemented(
+    message = "no implementation for `{Self} >>= {Rhs}`",
+    label = "no implementation for `{Self} >>= {Rhs}`"
+)]
+pub trait ShrAssign<Rhs = Self> {
+    /// Performs the `>>=` operation.
+    #[stable(feature = "op_assign_traits", since = "1.8.0")]
+    fn shr_assign(&mut self, rhs: Rhs);
+}
+
+macro_rules! shr_assign_impl {
+    ($t:ty, $f:ty) => {
+        #[stable(feature = "op_assign_traits", since = "1.8.0")]
+        impl ShrAssign<$f> for $t {
+            #[inline]
+            #[rustc_inherit_overflow_checks]
+            fn shr_assign(&mut self, other: $f) {
+                *self >>= other
+            }
+        }
+
+        forward_ref_op_assign! { impl ShrAssign, shr_assign for $t, $f }
+    };
+}
+
+macro_rules! shr_assign_impl_all {
+    ($($t:ty)*) => ($(
+        shr_assign_impl! { $t, u8 }
+        shr_assign_impl! { $t, u16 }
+        shr_assign_impl! { $t, u32 }
+        shr_assign_impl! { $t, u64 }
+        shr_assign_impl! { $t, u128 }
+        shr_assign_impl! { $t, usize }
+
+        shr_assign_impl! { $t, i8 }
+        shr_assign_impl! { $t, i16 }
+        shr_assign_impl! { $t, i32 }
+        shr_assign_impl! { $t, i64 }
+        shr_assign_impl! { $t, i128 }
+        shr_assign_impl! { $t, isize }
+    )*)
+}
+
+shr_assign_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
new file mode 100644
index 00000000000..3faeb170b06
--- /dev/null
+++ b/library/core/src/ops/deref.rs
@@ -0,0 +1,194 @@
+/// Used for immutable dereferencing operations, like `*v`.
+///
+/// In addition to being used for explicit dereferencing operations with the
+/// (unary) `*` operator in immutable contexts, `Deref` is also used implicitly
+/// by the compiler in many circumstances. This mechanism is called
+/// ['`Deref` coercion'][more]. In mutable contexts, [`DerefMut`] is used.
+///
+/// Implementing `Deref` for smart pointers makes accessing the data behind them
+/// convenient, which is why they implement `Deref`. On the other hand, the
+/// rules regarding `Deref` and [`DerefMut`] were designed specifically to
+/// accommodate smart pointers. Because of this, **`Deref` should only be
+/// implemented for smart pointers** to avoid confusion.
+///
+/// For similar reasons, **this trait should never fail**. Failure during
+/// dereferencing can be extremely confusing when `Deref` is invoked implicitly.
+///
+/// # More on `Deref` coercion
+///
+/// If `T` implements `Deref<Target = U>`, and `x` is a value of type `T`, then:
+///
+/// * In immutable contexts, `*x` (where `T` is neither a reference nor a raw pointer)
+///   is equivalent to `*Deref::deref(&x)`.
+/// * Values of type `&T` are coerced to values of type `&U`
+/// * `T` implicitly implements all the (immutable) methods of the type `U`.
+///
+/// For more details, visit [the chapter in *The Rust Programming Language*][book]
+/// as well as the reference sections on [the dereference operator][ref-deref-op],
+/// [method resolution] and [type coercions].
+///
+/// [book]: ../../book/ch15-02-deref.html
+/// [`DerefMut`]: trait.DerefMut.html
+/// [more]: #more-on-deref-coercion
+/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
+/// [method resolution]: ../../reference/expressions/method-call-expr.html
+/// [type coercions]: ../../reference/type-coercions.html
+///
+/// # Examples
+///
+/// A struct with a single field which is accessible by dereferencing the
+/// struct.
+///
+/// ```
+/// use std::ops::Deref;
+///
+/// struct DerefExample<T> {
+///     value: T
+/// }
+///
+/// impl<T> Deref for DerefExample<T> {
+///     type Target = T;
+///
+///     fn deref(&self) -> &Self::Target {
+///         &self.value
+///     }
+/// }
+///
+/// let x = DerefExample { value: 'a' };
+/// assert_eq!('a', *x);
+/// ```
+#[lang = "deref"]
+#[doc(alias = "*")]
+#[doc(alias = "&*")]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Deref {
+    /// The resulting type after dereferencing.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Target: ?Sized;
+
+    /// Dereferences the value.
+    #[must_use]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn deref(&self) -> &Self::Target;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> Deref for &T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> !DerefMut for &T {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> Deref for &mut T {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        *self
+    }
+}
+
+/// Used for mutable dereferencing operations, like in `*v = 1;`.
+///
+/// In addition to being used for explicit dereferencing operations with the
+/// (unary) `*` operator in mutable contexts, `DerefMut` is also used implicitly
+/// by the compiler in many circumstances. This mechanism is called
+/// ['`Deref` coercion'][more]. In immutable contexts, [`Deref`] is used.
+///
+/// Implementing `DerefMut` for smart pointers makes mutating the data behind
+/// them convenient, which is why they implement `DerefMut`. On the other hand,
+/// the rules regarding [`Deref`] and `DerefMut` were designed specifically to
+/// accommodate smart pointers. Because of this, **`DerefMut` should only be
+/// implemented for smart pointers** to avoid confusion.
+///
+/// For similar reasons, **this trait should never fail**. Failure during
+/// dereferencing can be extremely confusing when `DerefMut` is invoked
+/// implicitly.
+///
+/// # More on `Deref` coercion
+///
+/// If `T` implements `DerefMut<Target = U>`, and `x` is a value of type `T`,
+/// then:
+///
+/// * In mutable contexts, `*x` (where `T` is neither a reference nor a raw pointer)
+///   is equivalent to `*DerefMut::deref_mut(&mut x)`.
+/// * Values of type `&mut T` are coerced to values of type `&mut U`
+/// * `T` implicitly implements all the (mutable) methods of the type `U`.
+///
+/// For more details, visit [the chapter in *The Rust Programming Language*][book]
+/// as well as the reference sections on [the dereference operator][ref-deref-op],
+/// [method resolution] and [type coercions].
+///
+/// [book]: ../../book/ch15-02-deref.html
+/// [`Deref`]: trait.Deref.html
+/// [more]: #more-on-deref-coercion
+/// [ref-deref-op]: ../../reference/expressions/operator-expr.html#the-dereference-operator
+/// [method resolution]: ../../reference/expressions/method-call-expr.html
+/// [type coercions]: ../../reference/type-coercions.html
+///
+/// # Examples
+///
+/// A struct with a single field which is modifiable by dereferencing the
+/// struct.
+///
+/// ```
+/// use std::ops::{Deref, DerefMut};
+///
+/// struct DerefMutExample<T> {
+///     value: T
+/// }
+///
+/// impl<T> Deref for DerefMutExample<T> {
+///     type Target = T;
+///
+///     fn deref(&self) -> &Self::Target {
+///         &self.value
+///     }
+/// }
+///
+/// impl<T> DerefMut for DerefMutExample<T> {
+///     fn deref_mut(&mut self) -> &mut Self::Target {
+///         &mut self.value
+///     }
+/// }
+///
+/// let mut x = DerefMutExample { value: 'a' };
+/// *x = 'b';
+/// assert_eq!('b', *x);
+/// ```
+#[lang = "deref_mut"]
+#[doc(alias = "*")]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait DerefMut: Deref {
+    /// Mutably dereferences the value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn deref_mut(&mut self) -> &mut Self::Target;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> DerefMut for &mut T {
+    fn deref_mut(&mut self) -> &mut T {
+        *self
+    }
+}
+
+/// Indicates that a struct can be used as a method receiver, without the
+/// `arbitrary_self_types` feature. This is implemented by stdlib pointer types like `Box<T>`,
+/// `Rc<T>`, `&T`, and `Pin<P>`.
+#[lang = "receiver"]
+#[unstable(feature = "receiver_trait", issue = "none")]
+#[doc(hidden)]
+pub trait Receiver {
+    // Empty.
+}
+
+#[unstable(feature = "receiver_trait", issue = "none")]
+impl<T: ?Sized> Receiver for &T {}
+
+#[unstable(feature = "receiver_trait", issue = "none")]
+impl<T: ?Sized> Receiver for &mut T {}
diff --git a/library/core/src/ops/drop.rs b/library/core/src/ops/drop.rs
new file mode 100644
index 00000000000..06cfc363636
--- /dev/null
+++ b/library/core/src/ops/drop.rs
@@ -0,0 +1,167 @@
+/// Custom code within the destructor.
+///
+/// When a value is no longer needed, Rust will run a "destructor" on that value.
+/// The most common way that a value is no longer needed is when it goes out of
+/// scope. Destructors may still run in other circumstances, but we're going to
+/// focus on scope for the examples here. To learn about some of those other cases,
+/// please see [the reference] section on destructors.
+///
+/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
+///
+/// This destructor consists of two components:
+/// - A call to `Drop::drop` for that value, if this special `Drop` trait is implemented for its type.
+/// - The automatically generated "drop glue" which recursively calls the destructors
+///     of the all fields of this value.
+///
+/// As Rust automatically calls the destructors of all contained fields,
+/// you don't have to implement `Drop` in most cases. But there are some cases where
+/// it is useful, for example for types which directly manage a resource.
+/// That resource may be memory, it may be a file descriptor, it may be a network socket.
+/// Once a value of that type is no longer going to be used, it should "clean up" its
+/// resource by freeing the memory or closing the file or socket. This is
+/// the job of a destructor, and therefore the job of `Drop::drop`.
+///
+/// ## Examples
+///
+/// To see destructors in action, let's take a look at the following program:
+///
+/// ```rust
+/// struct HasDrop;
+///
+/// impl Drop for HasDrop {
+///     fn drop(&mut self) {
+///         println!("Dropping HasDrop!");
+///     }
+/// }
+///
+/// struct HasTwoDrops {
+///     one: HasDrop,
+///     two: HasDrop,
+/// }
+///
+/// impl Drop for HasTwoDrops {
+///     fn drop(&mut self) {
+///         println!("Dropping HasTwoDrops!");
+///     }
+/// }
+///
+/// fn main() {
+///     let _x = HasTwoDrops { one: HasDrop, two: HasDrop };
+///     println!("Running!");
+/// }
+/// ```
+///
+/// Rust will first call `Drop::drop` for `_x` and then for both `_x.one` and `_x.two`,
+/// meaning that running this will print
+///
+/// ```text
+/// Running!
+/// Dropping HasTwoDrops!
+/// Dropping HasDrop!
+/// Dropping HasDrop!
+/// ```
+///
+/// Even if we remove the implementation of `Drop` for `HasTwoDrop`, the destructors of its fields are still called.
+/// This would result in
+///
+/// ```test
+/// Running!
+/// Dropping HasDrop!
+/// Dropping HasDrop!
+/// ```
+///
+/// ## You cannot call `Drop::drop` yourself
+///
+/// Because `Drop::drop` is used to clean up a value, it may be dangerous to use this value after
+/// the method has been called. As `Drop::drop` does not take ownership of its input,
+/// Rust prevents misuse by not allowing you to call `Drop::drop` directly.
+///
+/// In other words, if you tried to explicitly call `Drop::drop` in the above example, you'd get a compiler error.
+///
+/// If you'd like explicitly call the destructor of a value, [`std::mem::drop`] can be used instead.
+///
+/// [`std::mem::drop`]: ../../std/mem/fn.drop.html
+///
+/// ## Drop order
+///
+/// Which of our two `HasDrop` drops first, though? For structs, it's the same
+/// order that they're declared: first `one`, then `two`. If you'd like to try
+/// this yourself, you can modify `HasDrop` above to contain some data, like an
+/// integer, and then use it in the `println!` inside of `Drop`. This behavior is
+/// guaranteed by the language.
+///
+/// Unlike for structs, local variables are dropped in reverse order:
+///
+/// ```rust
+/// struct Foo;
+///
+/// impl Drop for Foo {
+///     fn drop(&mut self) {
+///         println!("Dropping Foo!")
+///     }
+/// }
+///
+/// struct Bar;
+///
+/// impl Drop for Bar {
+///     fn drop(&mut self) {
+///         println!("Dropping Bar!")
+///     }
+/// }
+///
+/// fn main() {
+///     let _foo = Foo;
+///     let _bar = Bar;
+/// }
+/// ```
+///
+/// This will print
+///
+/// ```text
+/// Dropping Bar!
+/// Dropping Foo!
+/// ```
+///
+/// Please see [the reference] for the full rules.
+///
+/// [the reference]: https://doc.rust-lang.org/reference/destructors.html
+///
+/// ## `Copy` and `Drop` are exclusive
+///
+/// You cannot implement both [`Copy`] and `Drop` on the same type. Types that
+/// are `Copy` get implicitly duplicated by the compiler, making it very
+/// hard to predict when, and how often destructors will be executed. As such,
+/// these types cannot have destructors.
+///
+/// [`Copy`]: ../../std/marker/trait.Copy.html
+#[lang = "drop"]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Drop {
+    /// Executes the destructor for this type.
+    ///
+    /// 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.
+    ///
+    /// When this method has been called, `self` has not yet been deallocated.
+    /// That only happens after the method is over.
+    /// If this wasn't the case, `self` would be a dangling reference.
+    ///
+    /// # Panics
+    ///
+    /// Given that a [`panic!`] will call `drop` as it unwinds, any [`panic!`]
+    /// in a `drop` implementation will likely abort.
+    ///
+    /// Note that even if this panics, the value is considered to be dropped;
+    /// you must not cause `drop` to be called again. This is normally automatically
+    /// handled by the compiler, but when using unsafe code, can sometimes occur
+    /// unintentionally, particularly when using [`std::ptr::drop_in_place`].
+    ///
+    /// [E0040]: ../../error-index.html#E0040
+    /// [`panic!`]: ../macro.panic.html
+    /// [`std::mem::drop`]: ../../std/mem/fn.drop.html
+    /// [`std::ptr::drop_in_place`]: ../../std/ptr/fn.drop_in_place.html
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn drop(&mut self);
+}
diff --git a/library/core/src/ops/function.rs b/library/core/src/ops/function.rs
new file mode 100644
index 00000000000..3e5cad2b185
--- /dev/null
+++ b/library/core/src/ops/function.rs
@@ -0,0 +1,289 @@
+/// The version of the call operator that takes an immutable receiver.
+///
+/// Instances of `Fn` can be called repeatedly without mutating state.
+///
+/// *This trait (`Fn`) is not to be confused with [function pointers]
+/// (`fn`).*
+///
+/// `Fn` is implemented automatically by closures which only take immutable
+/// references to captured variables or don't capture anything at all, as well
+/// as (safe) [function pointers] (with some caveats, see their documentation
+/// for more details). Additionally, for any type `F` that implements `Fn`, `&F`
+/// implements `Fn`, too.
+///
+/// Since both [`FnMut`] and [`FnOnce`] are supertraits of `Fn`, any
+/// instance of `Fn` can be used as a parameter where a [`FnMut`] or [`FnOnce`]
+/// is expected.
+///
+/// Use `Fn` as a bound when you want to accept a parameter of function-like
+/// type and need to call it repeatedly and without mutating state (e.g., when
+/// calling it concurrently). If you do not need such strict requirements, use
+/// [`FnMut`] or [`FnOnce`] as bounds.
+///
+/// See the [chapter on closures in *The Rust Programming Language*][book] for
+/// some more information on this topic.
+///
+/// Also of note is the special syntax for `Fn` traits (e.g.
+/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
+/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
+///
+/// [book]: ../../book/ch13-01-closures.html
+/// [`FnMut`]: trait.FnMut.html
+/// [`FnOnce`]: trait.FnOnce.html
+/// [function pointers]: ../../std/primitive.fn.html
+/// [nomicon]: ../../nomicon/hrtb.html
+///
+/// # Examples
+///
+/// ## Calling a closure
+///
+/// ```
+/// let square = |x| x * x;
+/// assert_eq!(square(5), 25);
+/// ```
+///
+/// ## Using a `Fn` parameter
+///
+/// ```
+/// fn call_with_one<F>(func: F) -> usize
+///     where F: Fn(usize) -> usize {
+///     func(1)
+/// }
+///
+/// let double = |x| x * 2;
+/// assert_eq!(call_with_one(double), 2);
+/// ```
+#[lang = "fn"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_paren_sugar]
+#[rustc_on_unimplemented(
+    on(
+        Args = "()",
+        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
+    ),
+    message = "expected a `{Fn}<{Args}>` closure, found `{Self}`",
+    label = "expected an `Fn<{Args}>` closure, found `{Self}`"
+)]
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait Fn<Args>: FnMut<Args> {
+    /// Performs the call operation.
+    #[unstable(feature = "fn_traits", issue = "29625")]
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
+
+/// The version of the call operator that takes a mutable receiver.
+///
+/// Instances of `FnMut` can be called repeatedly and may mutate state.
+///
+/// `FnMut` is implemented automatically by closures which take mutable
+/// references to captured variables, as well as all types that implement
+/// [`Fn`], e.g., (safe) [function pointers] (since `FnMut` is a supertrait of
+/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`
+/// implements `FnMut`, too.
+///
+/// Since [`FnOnce`] is a supertrait of `FnMut`, any instance of `FnMut` can be
+/// used where a [`FnOnce`] is expected, and since [`Fn`] is a subtrait of
+/// `FnMut`, any instance of [`Fn`] can be used where `FnMut` is expected.
+///
+/// Use `FnMut` as a bound when you want to accept a parameter of function-like
+/// type and need to call it repeatedly, while allowing it to mutate state.
+/// If you don't want the parameter to mutate state, use [`Fn`] as a
+/// bound; if you don't need to call it repeatedly, use [`FnOnce`].
+///
+/// See the [chapter on closures in *The Rust Programming Language*][book] for
+/// some more information on this topic.
+///
+/// Also of note is the special syntax for `Fn` traits (e.g.
+/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
+/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
+///
+/// [book]: ../../book/ch13-01-closures.html
+/// [`Fn`]: trait.Fn.html
+/// [`FnOnce`]: trait.FnOnce.html
+/// [function pointers]: ../../std/primitive.fn.html
+/// [nomicon]: ../../nomicon/hrtb.html
+///
+/// # Examples
+///
+/// ## Calling a mutably capturing closure
+///
+/// ```
+/// let mut x = 5;
+/// {
+///     let mut square_x = || x *= x;
+///     square_x();
+/// }
+/// assert_eq!(x, 25);
+/// ```
+///
+/// ## Using a `FnMut` parameter
+///
+/// ```
+/// fn do_twice<F>(mut func: F)
+///     where F: FnMut()
+/// {
+///     func();
+///     func();
+/// }
+///
+/// let mut x: usize = 1;
+/// {
+///     let add_two_to_x = || x += 2;
+///     do_twice(add_two_to_x);
+/// }
+///
+/// assert_eq!(x, 5);
+/// ```
+#[lang = "fn_mut"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_paren_sugar]
+#[rustc_on_unimplemented(
+    on(
+        Args = "()",
+        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
+    ),
+    message = "expected a `{FnMut}<{Args}>` closure, found `{Self}`",
+    label = "expected an `FnMut<{Args}>` closure, found `{Self}`"
+)]
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnMut<Args>: FnOnce<Args> {
+    /// Performs the call operation.
+    #[unstable(feature = "fn_traits", issue = "29625")]
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
+}
+
+/// The version of the call operator that takes a by-value receiver.
+///
+/// Instances of `FnOnce` can be called, but might not be callable multiple
+/// times. Because of this, if the only thing known about a type is that it
+/// implements `FnOnce`, it can only be called once.
+///
+/// `FnOnce` is implemented automatically by closures that might consume captured
+/// variables, as well as all types that implement [`FnMut`], e.g., (safe)
+/// [function pointers] (since `FnOnce` is a supertrait of [`FnMut`]).
+///
+/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of
+/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected.
+///
+/// Use `FnOnce` as a bound when you want to accept a parameter of function-like
+/// type and only need to call it once. If you need to call the parameter
+/// repeatedly, use [`FnMut`] as a bound; if you also need it to not mutate
+/// state, use [`Fn`].
+///
+/// See the [chapter on closures in *The Rust Programming Language*][book] for
+/// some more information on this topic.
+///
+/// Also of note is the special syntax for `Fn` traits (e.g.
+/// `Fn(usize, bool) -> usize`). Those interested in the technical details of
+/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].
+///
+/// [book]: ../../book/ch13-01-closures.html
+/// [`Fn`]: trait.Fn.html
+/// [`FnMut`]: trait.FnMut.html
+/// [function pointers]: ../../std/primitive.fn.html
+/// [nomicon]: ../../nomicon/hrtb.html
+///
+/// # Examples
+///
+/// ## Using a `FnOnce` parameter
+///
+/// ```
+/// fn consume_with_relish<F>(func: F)
+///     where F: FnOnce() -> String
+/// {
+///     // `func` consumes its captured variables, so it cannot be run more
+///     // than once.
+///     println!("Consumed: {}", func());
+///
+///     println!("Delicious!");
+///
+///     // Attempting to invoke `func()` again will throw a `use of moved
+///     // value` error for `func`.
+/// }
+///
+/// let x = String::from("x");
+/// let consume_and_return_x = move || x;
+/// consume_with_relish(consume_and_return_x);
+///
+/// // `consume_and_return_x` can no longer be invoked at this point
+/// ```
+#[lang = "fn_once"]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_paren_sugar]
+#[rustc_on_unimplemented(
+    on(
+        Args = "()",
+        note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
+    ),
+    message = "expected a `{FnOnce}<{Args}>` closure, found `{Self}`",
+    label = "expected an `FnOnce<{Args}>` closure, found `{Self}`"
+)]
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+#[must_use = "closures are lazy and do nothing unless called"]
+pub trait FnOnce<Args> {
+    /// The returned type after the call operator is used.
+    #[lang = "fn_once_output"]
+    #[stable(feature = "fn_once_output", since = "1.12.0")]
+    type Output;
+
+    /// Performs the call operation.
+    #[unstable(feature = "fn_traits", issue = "29625")]
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+mod impls {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<A, F: ?Sized> Fn<A> for &F
+    where
+        F: Fn<A>,
+    {
+        extern "rust-call" fn call(&self, args: A) -> F::Output {
+            (**self).call(args)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<A, F: ?Sized> FnMut<A> for &F
+    where
+        F: Fn<A>,
+    {
+        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
+            (**self).call(args)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<A, F: ?Sized> FnOnce<A> for &F
+    where
+        F: Fn<A>,
+    {
+        type Output = F::Output;
+
+        extern "rust-call" fn call_once(self, args: A) -> F::Output {
+            (*self).call(args)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<A, F: ?Sized> FnMut<A> for &mut F
+    where
+        F: FnMut<A>,
+    {
+        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
+            (*self).call_mut(args)
+        }
+    }
+
+    #[stable(feature = "rust1", since = "1.0.0")]
+    impl<A, F: ?Sized> FnOnce<A> for &mut F
+    where
+        F: FnMut<A>,
+    {
+        type Output = F::Output;
+        extern "rust-call" fn call_once(self, args: A) -> F::Output {
+            (*self).call_mut(args)
+        }
+    }
+}
diff --git a/library/core/src/ops/generator.rs b/library/core/src/ops/generator.rs
new file mode 100644
index 00000000000..4f23620b92b
--- /dev/null
+++ b/library/core/src/ops/generator.rs
@@ -0,0 +1,134 @@
+use crate::marker::Unpin;
+use crate::pin::Pin;
+
+/// The result of a generator resumption.
+///
+/// This enum is returned from the `Generator::resume` method and indicates the
+/// possible return values of a generator. Currently this corresponds to either
+/// a suspension point (`Yielded`) or a termination point (`Complete`).
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[lang = "generator_state"]
+#[unstable(feature = "generator_trait", issue = "43122")]
+pub enum GeneratorState<Y, R> {
+    /// The generator suspended with a value.
+    ///
+    /// This state indicates that a generator has been suspended, and typically
+    /// corresponds to a `yield` statement. The value provided in this variant
+    /// corresponds to the expression passed to `yield` and allows generators to
+    /// provide a value each time they yield.
+    Yielded(Y),
+
+    /// The generator completed with a return value.
+    ///
+    /// This state indicates that a generator has finished execution with the
+    /// provided value. Once a generator has returned `Complete` it is
+    /// considered a programmer error to call `resume` again.
+    Complete(R),
+}
+
+/// The trait implemented by builtin generator types.
+///
+/// Generators, also commonly referred to as coroutines, are currently an
+/// experimental language feature in Rust. Added in [RFC 2033] generators are
+/// currently intended to primarily provide a building block for async/await
+/// syntax but will likely extend to also providing an ergonomic definition for
+/// iterators and other primitives.
+///
+/// The syntax and semantics for generators is unstable and will require a
+/// further RFC for stabilization. At this time, though, the syntax is
+/// closure-like:
+///
+/// ```rust
+/// #![feature(generators, generator_trait)]
+///
+/// use std::ops::{Generator, GeneratorState};
+/// use std::pin::Pin;
+///
+/// fn main() {
+///     let mut generator = || {
+///         yield 1;
+///         return "foo"
+///     };
+///
+///     match Pin::new(&mut generator).resume(()) {
+///         GeneratorState::Yielded(1) => {}
+///         _ => panic!("unexpected return from resume"),
+///     }
+///     match Pin::new(&mut generator).resume(()) {
+///         GeneratorState::Complete("foo") => {}
+///         _ => panic!("unexpected return from resume"),
+///     }
+/// }
+/// ```
+///
+/// More documentation of generators can be found in the unstable book.
+///
+/// [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
+#[lang = "generator"]
+#[unstable(feature = "generator_trait", issue = "43122")]
+#[fundamental]
+pub trait Generator<R = ()> {
+    /// The type of value this generator yields.
+    ///
+    /// This associated type corresponds to the `yield` expression and the
+    /// values which are allowed to be returned each time a generator yields.
+    /// For example an iterator-as-a-generator would likely have this type as
+    /// `T`, the type being iterated over.
+    type Yield;
+
+    /// The type of value this generator returns.
+    ///
+    /// This corresponds to the type returned from a generator either with a
+    /// `return` statement or implicitly as the last expression of a generator
+    /// literal. For example futures would use this as `Result<T, E>` as it
+    /// represents a completed future.
+    type Return;
+
+    /// Resumes the execution of this generator.
+    ///
+    /// This function will resume execution of the generator or start execution
+    /// if it hasn't already. This call will return back into the generator's
+    /// last suspension point, resuming execution from the latest `yield`. The
+    /// generator will continue executing until it either yields or returns, at
+    /// which point this function will return.
+    ///
+    /// # Return value
+    ///
+    /// The `GeneratorState` enum returned from this function indicates what
+    /// state the generator is in upon returning. If the `Yielded` variant is
+    /// returned then the generator has reached a suspension point and a value
+    /// has been yielded out. Generators in this state are available for
+    /// resumption at a later point.
+    ///
+    /// If `Complete` is returned then the generator has completely finished
+    /// with the value provided. It is invalid for the generator to be resumed
+    /// again.
+    ///
+    /// # Panics
+    ///
+    /// This function may panic if it is called after the `Complete` variant has
+    /// 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(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
+}
+
+#[unstable(feature = "generator_trait", issue = "43122")]
+impl<G: ?Sized + Generator<R>, R> Generator<R> for Pin<&mut G> {
+    type Yield = G::Yield;
+    type Return = G::Return;
+
+    fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
+        G::resume((*self).as_mut(), arg)
+    }
+}
+
+#[unstable(feature = "generator_trait", issue = "43122")]
+impl<G: ?Sized + Generator<R> + Unpin, R> Generator<R> for &mut G {
+    type Yield = G::Yield;
+    type Return = G::Return;
+
+    fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
+        G::resume(Pin::new(&mut *self), arg)
+    }
+}
diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs
new file mode 100644
index 00000000000..763b33606fe
--- /dev/null
+++ b/library/core/src/ops/index.rs
@@ -0,0 +1,172 @@
+/// Used for indexing operations (`container[index]`) in immutable contexts.
+///
+/// `container[index]` is actually syntactic sugar for `*container.index(index)`,
+/// but only when used as an immutable value. If a mutable value is requested,
+/// [`IndexMut`] is used instead. This allows nice things such as
+/// `let value = v[index]` if the type of `value` implements [`Copy`].
+///
+/// [`IndexMut`]: ../../std/ops/trait.IndexMut.html
+/// [`Copy`]: ../../std/marker/trait.Copy.html
+///
+/// # Examples
+///
+/// The following example implements `Index` on a read-only `NucleotideCount`
+/// container, enabling individual counts to be retrieved with index syntax.
+///
+/// ```
+/// use std::ops::Index;
+///
+/// enum Nucleotide {
+///     A,
+///     C,
+///     G,
+///     T,
+/// }
+///
+/// struct NucleotideCount {
+///     a: usize,
+///     c: usize,
+///     g: usize,
+///     t: usize,
+/// }
+///
+/// impl Index<Nucleotide> for NucleotideCount {
+///     type Output = usize;
+///
+///     fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
+///         match nucleotide {
+///             Nucleotide::A => &self.a,
+///             Nucleotide::C => &self.c,
+///             Nucleotide::G => &self.g,
+///             Nucleotide::T => &self.t,
+///         }
+///     }
+/// }
+///
+/// let nucleotide_count = NucleotideCount {a: 14, c: 9, g: 10, t: 12};
+/// assert_eq!(nucleotide_count[Nucleotide::A], 14);
+/// assert_eq!(nucleotide_count[Nucleotide::C], 9);
+/// assert_eq!(nucleotide_count[Nucleotide::G], 10);
+/// assert_eq!(nucleotide_count[Nucleotide::T], 12);
+/// ```
+#[lang = "index"]
+#[rustc_on_unimplemented(
+    message = "the type `{Self}` cannot be indexed by `{Idx}`",
+    label = "`{Self}` cannot be indexed by `{Idx}`"
+)]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(alias = "]")]
+#[doc(alias = "[")]
+#[doc(alias = "[]")]
+pub trait Index<Idx: ?Sized> {
+    /// The returned type after indexing.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Output: ?Sized;
+
+    /// Performs the indexing (`container[index]`) operation.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[track_caller]
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+/// Used for indexing operations (`container[index]`) in mutable contexts.
+///
+/// `container[index]` is actually syntactic sugar for
+/// `*container.index_mut(index)`, but only when used as a mutable value. If
+/// an immutable value is requested, the [`Index`] trait is used instead. This
+/// allows nice things such as `v[index] = value`.
+///
+/// [`Index`]: ../../std/ops/trait.Index.html
+///
+/// # Examples
+///
+/// A very simple implementation of a `Balance` struct that has two sides, where
+/// each can be indexed mutably and immutably.
+///
+/// ```
+/// use std::ops::{Index,IndexMut};
+///
+/// #[derive(Debug)]
+/// enum Side {
+///     Left,
+///     Right,
+/// }
+///
+/// #[derive(Debug, PartialEq)]
+/// enum Weight {
+///     Kilogram(f32),
+///     Pound(f32),
+/// }
+///
+/// struct Balance {
+///     pub left: Weight,
+///     pub right: Weight,
+/// }
+///
+/// impl Index<Side> for Balance {
+///     type Output = Weight;
+///
+///     fn index(&self, index: Side) -> &Self::Output {
+///         println!("Accessing {:?}-side of balance immutably", index);
+///         match index {
+///             Side::Left => &self.left,
+///             Side::Right => &self.right,
+///         }
+///     }
+/// }
+///
+/// impl IndexMut<Side> for Balance {
+///     fn index_mut(&mut self, index: Side) -> &mut Self::Output {
+///         println!("Accessing {:?}-side of balance mutably", index);
+///         match index {
+///             Side::Left => &mut self.left,
+///             Side::Right => &mut self.right,
+///         }
+///     }
+/// }
+///
+/// let mut balance = Balance {
+///     right: Weight::Kilogram(2.5),
+///     left: Weight::Pound(1.5),
+/// };
+///
+/// // In this case, `balance[Side::Right]` is sugar for
+/// // `*balance.index(Side::Right)`, since we are only *reading*
+/// // `balance[Side::Right]`, not writing it.
+/// assert_eq!(balance[Side::Right], Weight::Kilogram(2.5));
+///
+/// // However, in this case `balance[Side::Left]` is sugar for
+/// // `*balance.index_mut(Side::Left)`, since we are writing
+/// // `balance[Side::Left]`.
+/// balance[Side::Left] = Weight::Kilogram(3.0);
+/// ```
+#[lang = "index_mut"]
+#[rustc_on_unimplemented(
+    on(
+        _Self = "&str",
+        note = "you can use `.chars().nth()` or `.bytes().nth()`
+see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
+    ),
+    on(
+        _Self = "str",
+        note = "you can use `.chars().nth()` or `.bytes().nth()`
+see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
+    ),
+    on(
+        _Self = "std::string::String",
+        note = "you can use `.chars().nth()` or `.bytes().nth()`
+see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
+    ),
+    message = "the type `{Self}` cannot be mutably indexed by `{Idx}`",
+    label = "`{Self}` cannot be mutably indexed by `{Idx}`"
+)]
+#[stable(feature = "rust1", since = "1.0.0")]
+#[doc(alias = "[")]
+#[doc(alias = "]")]
+#[doc(alias = "[]")]
+pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
+    /// Performs the mutable indexing (`container[index]`) operation.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    #[track_caller]
+    fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
+}
diff --git a/library/core/src/ops/mod.rs b/library/core/src/ops/mod.rs
new file mode 100644
index 00000000000..e3e5934b44b
--- /dev/null
+++ b/library/core/src/ops/mod.rs
@@ -0,0 +1,199 @@
+//! Overloadable operators.
+//!
+//! Implementing these traits allows you to overload certain operators.
+//!
+//! Some of these traits are imported by the prelude, so they are available in
+//! every Rust program. Only operators backed by traits can be overloaded. For
+//! example, the addition operator (`+`) can be overloaded through the [`Add`]
+//! trait, but since the assignment operator (`=`) has no backing trait, there
+//! is no way of overloading its semantics. Additionally, this module does not
+//! provide any mechanism to create new operators. If traitless overloading or
+//! custom operators are required, you should look toward macros or compiler
+//! plugins to extend Rust's syntax.
+//!
+//! Implementations of operator traits should be unsurprising in their
+//! respective contexts, keeping in mind their usual meanings and
+//! [operator precedence]. For example, when implementing [`Mul`], the operation
+//! should have some resemblance to multiplication (and share expected
+//! properties like associativity).
+//!
+//! Note that the `&&` and `||` operators short-circuit, i.e., they only
+//! evaluate their second operand if it contributes to the result. Since this
+//! behavior is not enforceable by traits, `&&` and `||` are not supported as
+//! overloadable operators.
+//!
+//! Many of the operators take their operands by value. In non-generic
+//! contexts involving built-in types, this is usually not a problem.
+//! However, using these operators in generic code, requires some
+//! attention if values have to be reused as opposed to letting the operators
+//! consume them. One option is to occasionally use [`clone`].
+//! Another option is to rely on the types involved providing additional
+//! operator implementations for references. For example, for a user-defined
+//! type `T` which is supposed to support addition, it is probably a good
+//! idea to have both `T` and `&T` implement the traits [`Add<T>`][`Add`] and
+//! [`Add<&T>`][`Add`] so that generic code can be written without unnecessary
+//! cloning.
+//!
+//! # Examples
+//!
+//! This example creates a `Point` struct that implements [`Add`] and [`Sub`],
+//! and then demonstrates adding and subtracting two `Point`s.
+//!
+//! ```rust
+//! use std::ops::{Add, Sub};
+//!
+//! #[derive(Debug, Copy, Clone, PartialEq)]
+//! struct Point {
+//!     x: i32,
+//!     y: i32,
+//! }
+//!
+//! impl Add for Point {
+//!     type Output = Point;
+//!
+//!     fn add(self, other: Point) -> Point {
+//!         Point {x: self.x + other.x, y: self.y + other.y}
+//!     }
+//! }
+//!
+//! impl Sub for Point {
+//!     type Output = Point;
+//!
+//!     fn sub(self, other: Point) -> Point {
+//!         Point {x: self.x - other.x, y: self.y - other.y}
+//!     }
+//! }
+//!
+//! assert_eq!(Point {x: 3, y: 3}, Point {x: 1, y: 0} + Point {x: 2, y: 3});
+//! assert_eq!(Point {x: -1, y: -3}, Point {x: 1, y: 0} - Point {x: 2, y: 3});
+//! ```
+//!
+//! See the documentation for each trait for an example implementation.
+//!
+//! The [`Fn`], [`FnMut`], and [`FnOnce`] traits are implemented by types that can be
+//! invoked like functions. Note that [`Fn`] takes `&self`, [`FnMut`] takes `&mut
+//! self` and [`FnOnce`] takes `self`. These correspond to the three kinds of
+//! methods that can be invoked on an instance: call-by-reference,
+//! call-by-mutable-reference, and call-by-value. The most common use of these
+//! traits is to act as bounds to higher-level functions that take functions or
+//! closures as arguments.
+//!
+//! Taking a [`Fn`] as a parameter:
+//!
+//! ```rust
+//! fn call_with_one<F>(func: F) -> usize
+//!     where F: Fn(usize) -> usize
+//! {
+//!     func(1)
+//! }
+//!
+//! let double = |x| x * 2;
+//! assert_eq!(call_with_one(double), 2);
+//! ```
+//!
+//! Taking a [`FnMut`] as a parameter:
+//!
+//! ```rust
+//! fn do_twice<F>(mut func: F)
+//!     where F: FnMut()
+//! {
+//!     func();
+//!     func();
+//! }
+//!
+//! let mut x: usize = 1;
+//! {
+//!     let add_two_to_x = || x += 2;
+//!     do_twice(add_two_to_x);
+//! }
+//!
+//! assert_eq!(x, 5);
+//! ```
+//!
+//! Taking a [`FnOnce`] as a parameter:
+//!
+//! ```rust
+//! fn consume_with_relish<F>(func: F)
+//!     where F: FnOnce() -> String
+//! {
+//!     // `func` consumes its captured variables, so it cannot be run more
+//!     // than once
+//!     println!("Consumed: {}", func());
+//!
+//!     println!("Delicious!");
+//!
+//!     // Attempting to invoke `func()` again will throw a `use of moved
+//!     // value` error for `func`
+//! }
+//!
+//! let x = String::from("x");
+//! let consume_and_return_x = move || x;
+//! consume_with_relish(consume_and_return_x);
+//!
+//! // `consume_and_return_x` can no longer be invoked at this point
+//! ```
+//!
+//! [`Fn`]: trait.Fn.html
+//! [`FnMut`]: trait.FnMut.html
+//! [`FnOnce`]: trait.FnOnce.html
+//! [`Add`]: trait.Add.html
+//! [`Sub`]: trait.Sub.html
+//! [`Mul`]: trait.Mul.html
+//! [`clone`]: ../clone/trait.Clone.html#tymethod.clone
+//! [operator precedence]: ../../reference/expressions.html#expression-precedence
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+mod arith;
+mod bit;
+mod deref;
+mod drop;
+mod function;
+mod generator;
+mod index;
+mod range;
+mod r#try;
+mod unsize;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::arith::{Add, Div, Mul, Neg, Rem, Sub};
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+pub use self::arith::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::bit::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
+#[stable(feature = "op_assign_traits", since = "1.8.0")]
+pub use self::bit::{BitAndAssign, BitOrAssign, BitXorAssign, ShlAssign, ShrAssign};
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::deref::{Deref, DerefMut};
+
+#[unstable(feature = "receiver_trait", issue = "none")]
+pub use self::deref::Receiver;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::drop::Drop;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::function::{Fn, FnMut, FnOnce};
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::index::{Index, IndexMut};
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub use self::range::{Range, RangeFrom, RangeFull, RangeTo};
+
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+pub use self::range::{Bound, RangeBounds, RangeInclusive, RangeToInclusive};
+
+#[unstable(feature = "try_trait", issue = "42327")]
+pub use self::r#try::Try;
+
+#[unstable(feature = "generator_trait", issue = "43122")]
+pub use self::generator::{Generator, GeneratorState};
+
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+pub use self::unsize::CoerceUnsized;
+
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+pub use self::unsize::DispatchFromDyn;
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
new file mode 100644
index 00000000000..179038d1977
--- /dev/null
+++ b/library/core/src/ops/range.rs
@@ -0,0 +1,885 @@
+use crate::fmt;
+use crate::hash::Hash;
+
+/// An unbounded range (`..`).
+///
+/// `RangeFull` is primarily used as a [slicing index], its shorthand is `..`.
+/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
+///
+/// # Examples
+///
+/// The `..` syntax is a `RangeFull`:
+///
+/// ```
+/// assert_eq!((..), std::ops::RangeFull);
+/// ```
+///
+/// It does not have an [`IntoIterator`] implementation, so you can't use it in
+/// a `for` loop directly. This won't compile:
+///
+/// ```compile_fail,E0277
+/// for i in .. {
+///    // ...
+/// }
+/// ```
+///
+/// Used as a [slicing index], `RangeFull` produces the full array as a slice.
+///
+/// ```
+/// let arr = [0, 1, 2, 3, 4];
+/// assert_eq!(arr[ ..  ], [0,1,2,3,4]);  // RangeFull
+/// assert_eq!(arr[ .. 3], [0,1,2    ]);
+/// assert_eq!(arr[ ..=3], [0,1,2,3  ]);
+/// assert_eq!(arr[1..  ], [  1,2,3,4]);
+/// assert_eq!(arr[1.. 3], [  1,2    ]);
+/// assert_eq!(arr[1..=3], [  1,2,3  ]);
+/// ```
+///
+/// [`IntoIterator`]: ../iter/trait.Iterator.html
+/// [`Iterator`]: ../iter/trait.IntoIterator.html
+/// [slicing index]: ../slice/trait.SliceIndex.html
+#[doc(alias = "..")]
+#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RangeFull;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl fmt::Debug for RangeFull {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(fmt, "..")
+    }
+}
+
+/// A (half-open) range bounded inclusively below and exclusively above
+/// (`start..end`).
+///
+/// The `Range` `start..end` contains all values with `x >= start` and
+/// `x < end`. It is empty unless `start < end`.
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!((3..5), std::ops::Range { start: 3, end: 5 });
+/// assert_eq!(3 + 4 + 5, (3..6).sum());
+///
+/// let arr = [0, 1, 2, 3, 4];
+/// assert_eq!(arr[ ..  ], [0,1,2,3,4]);
+/// assert_eq!(arr[ .. 3], [0,1,2    ]);
+/// assert_eq!(arr[ ..=3], [0,1,2,3  ]);
+/// assert_eq!(arr[1..  ], [  1,2,3,4]);
+/// assert_eq!(arr[1.. 3], [  1,2    ]);  // Range
+/// assert_eq!(arr[1..=3], [  1,2,3  ]);
+/// ```
+#[doc(alias = "..")]
+#[derive(Clone, Default, PartialEq, Eq, Hash)] // not Copy -- see #27186
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct Range<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub start: Idx,
+    /// The upper bound of the range (exclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub end: Idx,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> Range<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!(!(3..5).contains(&2));
+    /// assert!( (3..5).contains(&3));
+    /// assert!( (3..5).contains(&4));
+    /// assert!(!(3..5).contains(&5));
+    ///
+    /// assert!(!(3..3).contains(&3));
+    /// assert!(!(3..2).contains(&3));
+    ///
+    /// assert!( (0.0..1.0).contains(&0.5));
+    /// assert!(!(0.0..1.0).contains(&f32::NAN));
+    /// assert!(!(0.0..f32::NAN).contains(&0.5));
+    /// assert!(!(f32::NAN..1.0).contains(&0.5));
+    /// ```
+    #[stable(feature = "range_contains", since = "1.35.0")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+
+    /// Returns `true` if the range contains no items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(range_is_empty)]
+    ///
+    /// assert!(!(3..5).is_empty());
+    /// assert!( (3..3).is_empty());
+    /// assert!( (3..2).is_empty());
+    /// ```
+    ///
+    /// The range is empty if either side is incomparable:
+    ///
+    /// ```
+    /// #![feature(range_is_empty)]
+    ///
+    /// assert!(!(3.0..5.0).is_empty());
+    /// assert!( (3.0..f32::NAN).is_empty());
+    /// assert!( (f32::NAN..5.0).is_empty());
+    /// ```
+    #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
+    pub fn is_empty(&self) -> bool {
+        !(self.start < self.end)
+    }
+}
+
+/// A range only bounded inclusively below (`start..`).
+///
+/// The `RangeFrom` `start..` contains all values with `x >= start`.
+///
+/// *Note*: Overflow in the [`Iterator`] implementation (when the contained
+/// data type reaches its numerical limit) is allowed to panic, wrap, or
+/// saturate. This behavior is defined by the implementation of the [`Step`]
+/// trait. For primitive integers, this follows the normal rules, and respects
+/// the overflow checks profile (panic in debug, wrap in release). Note also
+/// that overflow happens earlier than you might assume: the overflow happens
+/// in the call to `next` that yields the maximum value, as the range must be
+/// set to a state to yield the next value.
+///
+/// [`Step`]: crate::iter::Step
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!((2..), std::ops::RangeFrom { start: 2 });
+/// assert_eq!(2 + 3 + 4, (2..).take(3).sum());
+///
+/// let arr = [0, 1, 2, 3, 4];
+/// assert_eq!(arr[ ..  ], [0,1,2,3,4]);
+/// assert_eq!(arr[ .. 3], [0,1,2    ]);
+/// assert_eq!(arr[ ..=3], [0,1,2,3  ]);
+/// assert_eq!(arr[1..  ], [  1,2,3,4]);  // RangeFrom
+/// assert_eq!(arr[1.. 3], [  1,2    ]);
+/// assert_eq!(arr[1..=3], [  1,2,3  ]);
+/// ```
+///
+/// [`Iterator`]: ../iter/trait.IntoIterator.html
+#[doc(alias = "..")]
+#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RangeFrom<Idx> {
+    /// The lower bound of the range (inclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub start: Idx,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..")?;
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!(!(3..).contains(&2));
+    /// assert!( (3..).contains(&3));
+    /// assert!( (3..).contains(&1_000_000_000));
+    ///
+    /// assert!( (0.0..).contains(&0.5));
+    /// assert!(!(0.0..).contains(&f32::NAN));
+    /// assert!(!(f32::NAN..).contains(&0.5));
+    /// ```
+    #[stable(feature = "range_contains", since = "1.35.0")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+}
+
+/// A range only bounded exclusively above (`..end`).
+///
+/// The `RangeTo` `..end` contains all values with `x < end`.
+/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
+///
+/// # Examples
+///
+/// The `..end` syntax is a `RangeTo`:
+///
+/// ```
+/// assert_eq!((..5), std::ops::RangeTo { end: 5 });
+/// ```
+///
+/// It does not have an [`IntoIterator`] implementation, so you can't use it in
+/// a `for` loop directly. This won't compile:
+///
+/// ```compile_fail,E0277
+/// // error[E0277]: the trait bound `std::ops::RangeTo<{integer}>:
+/// // std::iter::Iterator` is not satisfied
+/// for i in ..5 {
+///     // ...
+/// }
+/// ```
+///
+/// When used as a [slicing index], `RangeTo` produces a slice of all array
+/// elements before the index indicated by `end`.
+///
+/// ```
+/// let arr = [0, 1, 2, 3, 4];
+/// assert_eq!(arr[ ..  ], [0,1,2,3,4]);
+/// assert_eq!(arr[ .. 3], [0,1,2    ]);  // RangeTo
+/// assert_eq!(arr[ ..=3], [0,1,2,3  ]);
+/// assert_eq!(arr[1..  ], [  1,2,3,4]);
+/// assert_eq!(arr[1.. 3], [  1,2    ]);
+/// assert_eq!(arr[1..=3], [  1,2,3  ]);
+/// ```
+///
+/// [`IntoIterator`]: ../iter/trait.Iterator.html
+/// [`Iterator`]: ../iter/trait.IntoIterator.html
+/// [slicing index]: ../slice/trait.SliceIndex.html
+#[doc(alias = "..")]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct RangeTo<Idx> {
+    /// The upper bound of the range (exclusive).
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub end: Idx,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(fmt, "..")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!( (..5).contains(&-1_000_000_000));
+    /// assert!( (..5).contains(&4));
+    /// assert!(!(..5).contains(&5));
+    ///
+    /// assert!( (..1.0).contains(&0.5));
+    /// assert!(!(..1.0).contains(&f32::NAN));
+    /// assert!(!(..f32::NAN).contains(&0.5));
+    /// ```
+    #[stable(feature = "range_contains", since = "1.35.0")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+}
+
+/// A range bounded inclusively below and above (`start..=end`).
+///
+/// The `RangeInclusive` `start..=end` contains all values with `x >= start`
+/// and `x <= end`. It is empty unless `start <= end`.
+///
+/// This iterator is [fused], but the specific values of `start` and `end` after
+/// iteration has finished are **unspecified** other than that [`.is_empty()`]
+/// will return `true` once no more values will be produced.
+///
+/// [fused]: ../iter/trait.FusedIterator.html
+/// [`.is_empty()`]: #method.is_empty
+///
+/// # Examples
+///
+/// ```
+/// assert_eq!((3..=5), std::ops::RangeInclusive::new(3, 5));
+/// assert_eq!(3 + 4 + 5, (3..=5).sum());
+///
+/// let arr = [0, 1, 2, 3, 4];
+/// assert_eq!(arr[ ..  ], [0,1,2,3,4]);
+/// assert_eq!(arr[ .. 3], [0,1,2    ]);
+/// assert_eq!(arr[ ..=3], [0,1,2,3  ]);
+/// assert_eq!(arr[1..  ], [  1,2,3,4]);
+/// assert_eq!(arr[1.. 3], [  1,2    ]);
+/// assert_eq!(arr[1..=3], [  1,2,3  ]);  // RangeInclusive
+/// ```
+#[doc(alias = "..=")]
+#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+pub struct RangeInclusive<Idx> {
+    // Note that the fields here are not public to allow changing the
+    // representation in the future; in particular, while we could plausibly
+    // expose start/end, modifying them without changing (future/current)
+    // private fields may lead to incorrect behavior, so we don't want to
+    // support that mode.
+    pub(crate) start: Idx,
+    pub(crate) end: Idx,
+
+    // This field is:
+    //  - `false` upon construction
+    //  - `false` when iteration has yielded an element and the iterator is not exhausted
+    //  - `true` when iteration has been used to exhaust the iterator
+    //
+    // This is required to support PartialEq and Hash without a PartialOrd bound or specialization.
+    pub(crate) exhausted: bool,
+}
+
+impl<Idx> RangeInclusive<Idx> {
+    /// Creates a new inclusive range. Equivalent to writing `start..=end`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ops::RangeInclusive;
+    ///
+    /// assert_eq!(3..=5, RangeInclusive::new(3, 5));
+    /// ```
+    #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
+    #[inline]
+    #[rustc_promotable]
+    #[rustc_const_stable(feature = "const_range_new", since = "1.32.0")]
+    pub const fn new(start: Idx, end: Idx) -> Self {
+        Self { start, end, exhausted: false }
+    }
+
+    /// Returns the lower bound of the range (inclusive).
+    ///
+    /// When using an inclusive range for iteration, the values of `start()` and
+    /// [`end()`] are unspecified after the iteration ended. To determine
+    /// whether the inclusive range is empty, use the [`is_empty()`] method
+    /// instead of comparing `start() > end()`.
+    ///
+    /// Note: the value returned by this method is unspecified after the range
+    /// has been iterated to exhaustion.
+    ///
+    /// [`end()`]: #method.end
+    /// [`is_empty()`]: #method.is_empty
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!((3..=5).start(), &3);
+    /// ```
+    #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
+    #[rustc_const_stable(feature = "const_inclusive_range_methods", since = "1.32.0")]
+    #[inline]
+    pub const fn start(&self) -> &Idx {
+        &self.start
+    }
+
+    /// Returns the upper bound of the range (inclusive).
+    ///
+    /// When using an inclusive range for iteration, the values of [`start()`]
+    /// and `end()` are unspecified after the iteration ended. To determine
+    /// whether the inclusive range is empty, use the [`is_empty()`] method
+    /// instead of comparing `start() > end()`.
+    ///
+    /// Note: the value returned by this method is unspecified after the range
+    /// has been iterated to exhaustion.
+    ///
+    /// [`start()`]: #method.start
+    /// [`is_empty()`]: #method.is_empty
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!((3..=5).end(), &5);
+    /// ```
+    #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
+    #[rustc_const_stable(feature = "const_inclusive_range_methods", since = "1.32.0")]
+    #[inline]
+    pub const fn end(&self) -> &Idx {
+        &self.end
+    }
+
+    /// Destructures the `RangeInclusive` into (lower bound, upper (inclusive) bound).
+    ///
+    /// Note: the value returned by this method is unspecified after the range
+    /// has been iterated to exhaustion.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!((3..=5).into_inner(), (3, 5));
+    /// ```
+    #[stable(feature = "inclusive_range_methods", since = "1.27.0")]
+    #[inline]
+    pub fn into_inner(self) -> (Idx, Idx) {
+        (self.start, self.end)
+    }
+}
+
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.start.fmt(fmt)?;
+        write!(fmt, "..=")?;
+        self.end.fmt(fmt)?;
+        if self.exhausted {
+            write!(fmt, " (exhausted)")?;
+        }
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!(!(3..=5).contains(&2));
+    /// assert!( (3..=5).contains(&3));
+    /// assert!( (3..=5).contains(&4));
+    /// assert!( (3..=5).contains(&5));
+    /// assert!(!(3..=5).contains(&6));
+    ///
+    /// assert!( (3..=3).contains(&3));
+    /// assert!(!(3..=2).contains(&3));
+    ///
+    /// assert!( (0.0..=1.0).contains(&1.0));
+    /// assert!(!(0.0..=1.0).contains(&f32::NAN));
+    /// assert!(!(0.0..=f32::NAN).contains(&0.0));
+    /// assert!(!(f32::NAN..=1.0).contains(&1.0));
+    /// ```
+    #[stable(feature = "range_contains", since = "1.35.0")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+
+    /// Returns `true` if the range contains no items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(range_is_empty)]
+    ///
+    /// assert!(!(3..=5).is_empty());
+    /// assert!(!(3..=3).is_empty());
+    /// assert!( (3..=2).is_empty());
+    /// ```
+    ///
+    /// The range is empty if either side is incomparable:
+    ///
+    /// ```
+    /// #![feature(range_is_empty)]
+    ///
+    /// assert!(!(3.0..=5.0).is_empty());
+    /// assert!( (3.0..=f32::NAN).is_empty());
+    /// assert!( (f32::NAN..=5.0).is_empty());
+    /// ```
+    ///
+    /// This method returns `true` after iteration has finished:
+    ///
+    /// ```
+    /// #![feature(range_is_empty)]
+    ///
+    /// let mut r = 3..=5;
+    /// for _ in r.by_ref() {}
+    /// // Precise field values are unspecified here
+    /// assert!(r.is_empty());
+    /// ```
+    #[unstable(feature = "range_is_empty", reason = "recently added", issue = "48111")]
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.exhausted || !(self.start <= self.end)
+    }
+}
+
+/// A range only bounded inclusively above (`..=end`).
+///
+/// The `RangeToInclusive` `..=end` contains all values with `x <= end`.
+/// It cannot serve as an [`Iterator`] because it doesn't have a starting point.
+///
+/// # Examples
+///
+/// The `..=end` syntax is a `RangeToInclusive`:
+///
+/// ```
+/// assert_eq!((..=5), std::ops::RangeToInclusive{ end: 5 });
+/// ```
+///
+/// It does not have an [`IntoIterator`] implementation, so you can't use it in a
+/// `for` loop directly. This won't compile:
+///
+/// ```compile_fail,E0277
+/// // error[E0277]: the trait bound `std::ops::RangeToInclusive<{integer}>:
+/// // std::iter::Iterator` is not satisfied
+/// for i in ..=5 {
+///     // ...
+/// }
+/// ```
+///
+/// When used as a [slicing index], `RangeToInclusive` produces a slice of all
+/// array elements up to and including the index indicated by `end`.
+///
+/// ```
+/// let arr = [0, 1, 2, 3, 4];
+/// assert_eq!(arr[ ..  ], [0,1,2,3,4]);
+/// assert_eq!(arr[ .. 3], [0,1,2    ]);
+/// assert_eq!(arr[ ..=3], [0,1,2,3  ]);  // RangeToInclusive
+/// assert_eq!(arr[1..  ], [  1,2,3,4]);
+/// assert_eq!(arr[1.. 3], [  1,2    ]);
+/// assert_eq!(arr[1..=3], [  1,2,3  ]);
+/// ```
+///
+/// [`IntoIterator`]: ../iter/trait.Iterator.html
+/// [`Iterator`]: ../iter/trait.IntoIterator.html
+/// [slicing index]: ../slice/trait.SliceIndex.html
+#[doc(alias = "..=")]
+#[derive(Copy, Clone, PartialEq, Eq, Hash)]
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+pub struct RangeToInclusive<Idx> {
+    /// The upper bound of the range (inclusive)
+    #[stable(feature = "inclusive_range", since = "1.26.0")]
+    pub end: Idx,
+}
+
+#[stable(feature = "inclusive_range", since = "1.26.0")]
+impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(fmt, "..=")?;
+        self.end.fmt(fmt)?;
+        Ok(())
+    }
+}
+
+impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!( (..=5).contains(&-1_000_000_000));
+    /// assert!( (..=5).contains(&5));
+    /// assert!(!(..=5).contains(&6));
+    ///
+    /// assert!( (..=1.0).contains(&1.0));
+    /// assert!(!(..=1.0).contains(&f32::NAN));
+    /// assert!(!(..=f32::NAN).contains(&0.5));
+    /// ```
+    #[stable(feature = "range_contains", since = "1.35.0")]
+    pub fn contains<U>(&self, item: &U) -> bool
+    where
+        Idx: PartialOrd<U>,
+        U: ?Sized + PartialOrd<Idx>,
+    {
+        <Self as RangeBounds<Idx>>::contains(self, item)
+    }
+}
+
+// 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:
+///
+/// ```
+/// use std::ops::Bound::*;
+/// use std::ops::RangeBounds;
+///
+/// assert_eq!((..100).start_bound(), Unbounded);
+/// assert_eq!((1..12).start_bound(), Included(&1));
+/// assert_eq!((1..12).end_bound(), 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,
+}
+
+impl<T: Clone> Bound<&T> {
+    /// Map a `Bound<&T>` to a `Bound<T>` by cloning the contents of the bound.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bound_cloned)]
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((1..12).start_bound(), Included(&1));
+    /// assert_eq!((1..12).start_bound().cloned(), Included(1));
+    /// ```
+    #[unstable(feature = "bound_cloned", issue = "61356")]
+    pub fn cloned(self) -> Bound<T> {
+        match self {
+            Bound::Unbounded => Bound::Unbounded,
+            Bound::Included(x) => Bound::Included(x.clone()),
+            Bound::Excluded(x) => Bound::Excluded(x.clone()),
+        }
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+/// `RangeBounds` is implemented by Rust's built-in range types, produced
+/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
+pub trait RangeBounds<T: ?Sized> {
+    /// Start index bound.
+    ///
+    /// Returns the start value as a `Bound`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn main() {
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((..10).start_bound(), Unbounded);
+    /// assert_eq!((3..10).start_bound(), Included(&3));
+    /// # }
+    /// ```
+    #[stable(feature = "collections_range", since = "1.28.0")]
+    fn start_bound(&self) -> Bound<&T>;
+
+    /// End index bound.
+    ///
+    /// Returns the end value as a `Bound`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # fn main() {
+    /// use std::ops::Bound::*;
+    /// use std::ops::RangeBounds;
+    ///
+    /// assert_eq!((3..).end_bound(), Unbounded);
+    /// assert_eq!((3..10).end_bound(), Excluded(&10));
+    /// # }
+    /// ```
+    #[stable(feature = "collections_range", since = "1.28.0")]
+    fn end_bound(&self) -> Bound<&T>;
+
+    /// Returns `true` if `item` is contained in the range.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert!( (3..5).contains(&4));
+    /// assert!(!(3..5).contains(&2));
+    ///
+    /// assert!( (0.0..1.0).contains(&0.5));
+    /// assert!(!(0.0..1.0).contains(&f32::NAN));
+    /// assert!(!(0.0..f32::NAN).contains(&0.5));
+    /// assert!(!(f32::NAN..1.0).contains(&0.5));
+    #[stable(feature = "range_contains", since = "1.35.0")]
+    fn contains<U>(&self, item: &U) -> bool
+    where
+        T: PartialOrd<U>,
+        U: ?Sized + PartialOrd<T>,
+    {
+        (match self.start_bound() {
+            Included(ref start) => *start <= item,
+            Excluded(ref start) => *start < item,
+            Unbounded => true,
+        }) && (match self.end_bound() {
+            Included(ref end) => item <= *end,
+            Excluded(ref end) => item < *end,
+            Unbounded => true,
+        })
+    }
+}
+
+use self::Bound::{Excluded, Included, Unbounded};
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T: ?Sized> RangeBounds<T> for RangeFull {
+    fn start_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeFrom<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeTo<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(&self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for Range<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(&self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeInclusive<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(&self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(&self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeToInclusive<T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(&self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for (Bound<T>, Bound<T>) {
+    fn start_bound(&self) -> Bound<&T> {
+        match *self {
+            (Included(ref start), _) => Included(start),
+            (Excluded(ref start), _) => Excluded(start),
+            (Unbounded, _) => Unbounded,
+        }
+    }
+
+    fn end_bound(&self) -> Bound<&T> {
+        match *self {
+            (_, Included(ref end)) => Included(end),
+            (_, Excluded(ref end)) => Excluded(end),
+            (_, Unbounded) => Unbounded,
+        }
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<'a, T: ?Sized + 'a> RangeBounds<T> for (Bound<&'a T>, Bound<&'a T>) {
+    fn start_bound(&self) -> Bound<&T> {
+        self.0
+    }
+
+    fn end_bound(&self) -> Bound<&T> {
+        self.1
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeFrom<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeTo<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for Range<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Excluded(self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeInclusive<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Included(self.start)
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(self.end)
+    }
+}
+
+#[stable(feature = "collections_range", since = "1.28.0")]
+impl<T> RangeBounds<T> for RangeToInclusive<&T> {
+    fn start_bound(&self) -> Bound<&T> {
+        Unbounded
+    }
+    fn end_bound(&self) -> Bound<&T> {
+        Included(self.end)
+    }
+}
diff --git a/library/core/src/ops/try.rs b/library/core/src/ops/try.rs
new file mode 100644
index 00000000000..9bc35ae1f5c
--- /dev/null
+++ b/library/core/src/ops/try.rs
@@ -0,0 +1,58 @@
+/// A trait for customizing the behavior of the `?` operator.
+///
+/// A type implementing `Try` is one that has a canonical way to view it
+/// in terms of a success/failure dichotomy. This trait allows both
+/// extracting those success or failure values from an existing instance and
+/// creating a new instance from a success or failure value.
+#[unstable(feature = "try_trait", issue = "42327")]
+#[rustc_on_unimplemented(
+    on(
+        all(
+            any(from_method = "from_error", from_method = "from_ok"),
+            from_desugaring = "QuestionMark"
+        ),
+        message = "the `?` operator can only be used in {ItemContext} \
+                    that returns `Result` or `Option` \
+                    (or another type that implements `{Try}`)",
+        label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
+        enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
+    ),
+    on(
+        all(from_method = "into_result", from_desugaring = "QuestionMark"),
+        message = "the `?` operator can only be applied to values \
+                    that implement `{Try}`",
+        label = "the `?` operator cannot be applied to type `{Self}`"
+    )
+)]
+#[doc(alias = "?")]
+#[lang = "try"]
+pub trait Try {
+    /// The type of this value when viewed as successful.
+    #[unstable(feature = "try_trait", issue = "42327")]
+    type Ok;
+    /// The type of this value when viewed as failed.
+    #[unstable(feature = "try_trait", issue = "42327")]
+    type Error;
+
+    /// Applies the "?" operator. A return of `Ok(t)` means that the
+    /// execution should continue normally, and the result of `?` is the
+    /// value `t`. A return of `Err(e)` means that execution should branch
+    /// to the innermost enclosing `catch`, or return from the function.
+    ///
+    /// If an `Err(e)` result is returned, the value `e` will be "wrapped"
+    /// in the return type of the enclosing scope (which must itself implement
+    /// `Try`). Specifically, the value `X::from_error(From::from(e))`
+    /// is returned, where `X` is the return type of the enclosing function.
+    #[unstable(feature = "try_trait", issue = "42327")]
+    fn into_result(self) -> Result<Self::Ok, Self::Error>;
+
+    /// Wrap an error value to construct the composite result. For example,
+    /// `Result::Err(x)` and `Result::from_error(x)` are equivalent.
+    #[unstable(feature = "try_trait", issue = "42327")]
+    fn from_error(v: Self::Error) -> Self;
+
+    /// Wrap an OK value to construct the composite result. For example,
+    /// `Result::Ok(x)` and `Result::from_ok(x)` are equivalent.
+    #[unstable(feature = "try_trait", issue = "42327")]
+    fn from_ok(v: Self::Ok) -> Self;
+}
diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs
new file mode 100644
index 00000000000..95a4393592b
--- /dev/null
+++ b/library/core/src/ops/unsize.rs
@@ -0,0 +1,101 @@
+use crate::marker::Unsize;
+
+/// Trait that indicates that this is a pointer or a wrapper for one,
+/// where unsizing can be performed on the pointee.
+///
+/// See the [DST coercion RFC][dst-coerce] and [the nomicon entry on coercion][nomicon-coerce]
+/// for more details.
+///
+/// For builtin pointer types, pointers to `T` will coerce to pointers to `U` if `T: Unsize<U>`
+/// by converting from a thin pointer to a fat pointer.
+///
+/// For custom types, the coercion here works by coercing `Foo<T>` to `Foo<U>`
+/// provided an impl of `CoerceUnsized<Foo<U>> for Foo<T>` exists.
+/// Such an impl can only be written if `Foo<T>` has only a single non-phantomdata
+/// field involving `T`. If the type of that field is `Bar<T>`, an implementation
+/// of `CoerceUnsized<Bar<U>> for Bar<T>` must exist. The coercion will work by
+/// coercing the `Bar<T>` field into `Bar<U>` and filling in the rest of the fields
+/// from `Foo<T>` to create a `Foo<U>`. This will effectively drill down to a pointer
+/// field and coerce that.
+///
+/// Generally, for smart pointers you will implement
+/// `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`, with an
+/// optional `?Sized` bound on `T` itself. For wrapper types that directly embed `T`
+/// like `Cell<T>` and `RefCell<T>`, you
+/// can directly implement `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`.
+/// This will let coercions of types like `Cell<Box<T>>` work.
+///
+/// [`Unsize`][unsize] is used to mark types which can be coerced to DSTs if behind
+/// pointers. It is implemented automatically by the compiler.
+///
+/// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
+/// [unsize]: ../marker/trait.Unsize.html
+/// [nomicon-coerce]: ../../nomicon/coercions.html
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T: ?Sized> {
+    // Empty.
+}
+
+// &mut T -> &mut U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
+// &mut T -> &U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
+// &mut T -> *mut U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
+// &mut T -> *const U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}
+
+// &T -> &U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
+// &T -> *const U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}
+
+// *mut T -> *mut U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
+// *mut T -> *const U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}
+
+// *const T -> *const U
+#[unstable(feature = "coerce_unsized", issue = "27732")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
+
+/// This is used for object safety, to check that a method's receiver type can be dispatched on.
+///
+/// An example implementation of the trait:
+///
+/// ```
+/// # #![feature(dispatch_from_dyn, unsize)]
+/// # use std::{ops::DispatchFromDyn, marker::Unsize};
+/// # struct Rc<T: ?Sized>(std::rc::Rc<T>);
+/// impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
+/// where
+///     T: Unsize<U>,
+/// {}
+/// ```
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+#[lang = "dispatch_from_dyn"]
+pub trait DispatchFromDyn<T> {
+    // Empty.
+}
+
+// &T -> &U
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+// &mut T -> &mut U
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
+// *const T -> *const U
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
+// *mut T -> *mut U
+#[unstable(feature = "dispatch_from_dyn", issue = "none")]
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}