summaryrefslogtreecommitdiffstats
path: root/library/core/src/ops
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /library/core/src/ops
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/core/src/ops')
-rw-r--r--library/core/src/ops/arith.rs1029
-rw-r--r--library/core/src/ops/bit.rs1044
-rw-r--r--library/core/src/ops/control_flow.rs299
-rw-r--r--library/core/src/ops/deref.rs199
-rw-r--r--library/core/src/ops/drop.rs165
-rw-r--r--library/core/src/ops/function.rs304
-rw-r--r--library/core/src/ops/generator.rs136
-rw-r--r--library/core/src/ops/index.rs175
-rw-r--r--library/core/src/ops/mod.rs208
-rw-r--r--library/core/src/ops/range.rs991
-rw-r--r--library/core/src/ops/try_trait.rs418
-rw-r--r--library/core/src/ops/unsize.rs132
12 files changed, 5100 insertions, 0 deletions
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
new file mode 100644
index 000000000..e367be8c1
--- /dev/null
+++ b/library/core/src/ops/arith.rs
@@ -0,0 +1,1029 @@
+/// 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")]
+#[cfg_attr(
+ bootstrap,
+ 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}`"
+ )
+)]
+#[cfg_attr(
+ not(bootstrap),
+ 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}`",
+ append_const_msg,
+ )
+)]
+#[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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 + 1, 13);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Add for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn add(self, other: $t) -> $t { self + other }
+ }
+
+ forward_ref_binop! { impl const 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 = Self;
+///
+/// fn sub(self, other: Self) -> Self::Output {
+/// Self {
+/// 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 - 1, 11);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Sub for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn sub(self, other: $t) -> $t { self - other }
+ }
+
+ forward_ref_binop! { impl const 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);
+/// Self {
+/// 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;
+/// Self::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 {
+/// Self { 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 `{Self}` by `{Rhs}`",
+ 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 * 2, 24);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Mul for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn mul(self, other: $t) -> $t { self * other }
+ }
+
+ forward_ref_binop! { impl const 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);
+/// Self {
+/// 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;
+/// Self::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 {
+/// Self { 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 / 2, 6);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn div(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! div_impl_integer {
+ ($(($($t:ty)*) => $panic:expr),*) => ($($(
+ /// This operation rounds towards zero, truncating any
+ /// fractional part of the exact result.
+ ///
+ /// # Panics
+ ///
+ #[doc = $panic]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Div for $t {
+ type Output = $t;
+
+ #[inline]
+ fn div(self, other: $t) -> $t { self / other }
+ }
+
+ forward_ref_binop! { impl const Div, div for $t, $t }
+ )*)*)
+}
+
+div_impl_integer! {
+ (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
+ (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or the division results in overflow."
+}
+
+macro_rules! div_impl_float {
+ ($($t:ty)*) => ($(
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Div for $t {
+ type Output = $t;
+
+ #[inline]
+ fn div(self, other: $t) -> $t { self / other }
+ }
+
+ forward_ref_binop! { impl const 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;
+/// Self {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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// assert_eq!(12 % 10, 2);
+ /// ```
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ fn rem(self, rhs: Rhs) -> Self::Output;
+}
+
+macro_rules! rem_impl_integer {
+ ($(($($t:ty)*) => $panic:expr),*) => ($($(
+ /// This operation satisfies `n % d == n - (n / d) * d`. The
+ /// result has the same sign as the left operand.
+ ///
+ /// # Panics
+ ///
+ #[doc = $panic]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Rem for $t {
+ type Output = $t;
+
+ #[inline]
+ fn rem(self, other: $t) -> $t { self % other }
+ }
+
+ forward_ref_binop! { impl const Rem, rem for $t, $t }
+ )*)*)
+}
+
+rem_impl_integer! {
+ (usize u8 u16 u32 u64 u128) => "This operation will panic if `other == 0`.",
+ (isize i8 i16 i32 i64 i128) => "This operation will panic if `other == 0` or if `self / other` results in overflow."
+}
+
+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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Rem for $t {
+ type Output = $t;
+
+ #[inline]
+ fn rem(self, other: $t) -> $t { self % other }
+ }
+
+ forward_ref_binop! { impl const 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 = Self;
+///
+/// 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let x: i32 = 12;
+ /// assert_eq!(-x, -12);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Neg for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn neg(self) -> $t { -self }
+ }
+
+ forward_ref_unop! { impl const 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x += 1;
+ /// assert_eq!(x, 13);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const AddAssign for $t {
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn add_assign(&mut self, other: $t) { *self += other }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x -= 1;
+ /// assert_eq!(x, 11);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const SubAssign for $t {
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn sub_assign(&mut self, other: $t) { *self -= other }
+ }
+
+ forward_ref_op_assign! { impl const 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 `{Self}` by `{Rhs}`",
+ label = "no implementation for `{Self} *= {Rhs}`"
+)]
+#[doc(alias = "*")]
+#[doc(alias = "*=")]
+pub trait MulAssign<Rhs = Self> {
+ /// Performs the `*=` operation.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x *= 2;
+ /// assert_eq!(x, 24);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const MulAssign for $t {
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn mul_assign(&mut self, other: $t) { *self *= other }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x /= 2;
+ /// assert_eq!(x, 6);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const DivAssign for $t {
+ #[inline]
+ fn div_assign(&mut self, other: $t) { *self /= other }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// let mut x: u32 = 12;
+ /// x %= 10;
+ /// assert_eq!(x, 2);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const RemAssign for $t {
+ #[inline]
+ fn rem_assign(&mut self, other: $t) { *self %= other }
+ }
+
+ forward_ref_op_assign! { impl const 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 000000000..7c664226f
--- /dev/null
+++ b/library/core/src/ops/bit.rs
@@ -0,0 +1,1044 @@
+/// 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 = Self;
+///
+/// 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")]
+#[doc(alias = "!")]
+pub trait Not {
+ /// The resulting type after applying the `!` operator.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ type Output;
+
+ /// Performs the unary `!` operation.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(!true, false);
+ /// assert_eq!(!false, true);
+ /// assert_eq!(!1u8, 254);
+ /// assert_eq!(!0u8, 255);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Not for $t {
+ type Output = $t;
+
+ #[inline]
+ fn not(self) -> $t { !self }
+ }
+
+ forward_ref_unop! { impl const Not, not for $t }
+ )*)
+}
+
+not_impl! { bool usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
+
+#[stable(feature = "not_never", since = "1.60.0")]
+#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+impl const Not for ! {
+ type Output = !;
+
+ #[inline]
+ fn not(self) -> ! {
+ match self {}
+ }
+}
+
+/// 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 {
+/// Self(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, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// assert_eq!(lhs.len(), rhs.len());
+/// Self(
+/// 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(true & false, false);
+ /// assert_eq!(true & true, true);
+ /// assert_eq!(5u8 & 1u8, 1);
+ /// assert_eq!(5u8 & 2u8, 0);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const BitAnd for $t {
+ type Output = $t;
+
+ #[inline]
+ fn bitand(self, rhs: $t) -> $t { self & rhs }
+ }
+
+ forward_ref_binop! { impl const 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::Output {
+/// Self(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, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// assert_eq!(lhs.len(), rhs.len());
+/// Self(
+/// 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(true | false, true);
+ /// assert_eq!(false | false, false);
+ /// assert_eq!(5u8 | 1u8, 5);
+ /// assert_eq!(5u8 | 2u8, 7);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const BitOr for $t {
+ type Output = $t;
+
+ #[inline]
+ fn bitor(self, rhs: $t) -> $t { self | rhs }
+ }
+
+ forward_ref_binop! { impl const 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 {
+/// Self(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, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// assert_eq!(lhs.len(), rhs.len());
+/// Self(
+/// 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![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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(true ^ false, true);
+ /// assert_eq!(true ^ true, false);
+ /// assert_eq!(5u8 ^ 1u8, 4);
+ /// assert_eq!(5u8 ^ 2u8, 7);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const BitXor for $t {
+ type Output = $t;
+
+ #[inline]
+ fn bitxor(self, other: $t) -> $t { self ^ other }
+ }
+
+ forward_ref_binop! { impl const 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, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// Self(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![];
+/// spun_vector.extend_from_slice(b);
+/// spun_vector.extend_from_slice(a);
+/// Self { 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(5u8 << 1, 10);
+ /// assert_eq!(1u8 << 1, 2);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Shl<$f> for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn shl(self, other: $f) -> $t {
+ self << other
+ }
+ }
+
+ forward_ref_binop! { impl const 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, Self(rhs): Self) -> Self::Output {
+/// let Self(lhs) = self;
+/// Self(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![];
+/// spun_vector.extend_from_slice(b);
+/// spun_vector.extend_from_slice(a);
+/// Self { 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(5u8 >> 1, 2);
+ /// assert_eq!(2u8 >> 1, 1);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const Shr<$f> for $t {
+ type Output = $t;
+
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn shr(self, other: $f) -> $t {
+ self >> other
+ }
+ }
+
+ forward_ref_binop! { impl const 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 = Self(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 = Self(
+/// 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x = true;
+ /// x &= false;
+ /// assert_eq!(x, false);
+ ///
+ /// let mut x = true;
+ /// x &= true;
+ /// assert_eq!(x, true);
+ ///
+ /// let mut x: u8 = 5;
+ /// x &= 1;
+ /// assert_eq!(x, 1);
+ ///
+ /// let mut x: u8 = 5;
+ /// x &= 2;
+ /// assert_eq!(x, 0);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const BitAndAssign for $t {
+ #[inline]
+ fn bitand_assign(&mut self, other: $t) { *self &= other }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x = true;
+ /// x |= false;
+ /// assert_eq!(x, true);
+ ///
+ /// let mut x = false;
+ /// x |= false;
+ /// assert_eq!(x, false);
+ ///
+ /// let mut x: u8 = 5;
+ /// x |= 1;
+ /// assert_eq!(x, 5);
+ ///
+ /// let mut x: u8 = 5;
+ /// x |= 2;
+ /// assert_eq!(x, 7);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const BitOrAssign for $t {
+ #[inline]
+ fn bitor_assign(&mut self, other: $t) { *self |= other }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x = true;
+ /// x ^= false;
+ /// assert_eq!(x, true);
+ ///
+ /// let mut x = true;
+ /// x ^= true;
+ /// assert_eq!(x, false);
+ ///
+ /// let mut x: u8 = 5;
+ /// x ^= 1;
+ /// assert_eq!(x, 4);
+ ///
+ /// let mut x: u8 = 5;
+ /// x ^= 2;
+ /// assert_eq!(x, 7);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const BitXorAssign for $t {
+ #[inline]
+ fn bitxor_assign(&mut self, other: $t) { *self ^= other }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x: u8 = 5;
+ /// x <<= 1;
+ /// assert_eq!(x, 10);
+ ///
+ /// let mut x: u8 = 1;
+ /// x <<= 1;
+ /// assert_eq!(x, 2);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const ShlAssign<$f> for $t {
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn shl_assign(&mut self, other: $f) {
+ *self <<= other
+ }
+ }
+
+ forward_ref_op_assign! { impl const 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.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut x: u8 = 5;
+ /// x >>= 1;
+ /// assert_eq!(x, 2);
+ ///
+ /// let mut x: u8 = 2;
+ /// x >>= 1;
+ /// assert_eq!(x, 1);
+ /// ```
+ #[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")]
+ #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+ impl const ShrAssign<$f> for $t {
+ #[inline]
+ #[rustc_inherit_overflow_checks]
+ fn shr_assign(&mut self, other: $f) {
+ *self >>= other
+ }
+ }
+
+ forward_ref_op_assign! { impl const 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/control_flow.rs b/library/core/src/ops/control_flow.rs
new file mode 100644
index 000000000..b1f5559dc
--- /dev/null
+++ b/library/core/src/ops/control_flow.rs
@@ -0,0 +1,299 @@
+use crate::{convert, ops};
+
+/// Used to tell an operation whether it should exit early or go on as usual.
+///
+/// This is used when exposing things (like graph traversals or visitors) where
+/// you want the user to be able to choose whether to exit early.
+/// Having the enum makes it clearer -- no more wondering "wait, what did `false`
+/// mean again?" -- and allows including a value.
+///
+/// Similar to [`Option`] and [`Result`], this enum can be used with the `?` operator
+/// to return immediately if the [`Break`] variant is present or otherwise continue normally
+/// with the value inside the [`Continue`] variant.
+///
+/// # Examples
+///
+/// Early-exiting from [`Iterator::try_for_each`]:
+/// ```
+/// use std::ops::ControlFlow;
+///
+/// let r = (2..100).try_for_each(|x| {
+/// if 403 % x == 0 {
+/// return ControlFlow::Break(x)
+/// }
+///
+/// ControlFlow::Continue(())
+/// });
+/// assert_eq!(r, ControlFlow::Break(13));
+/// ```
+///
+/// A basic tree traversal:
+/// ```
+/// use std::ops::ControlFlow;
+///
+/// pub struct TreeNode<T> {
+/// value: T,
+/// left: Option<Box<TreeNode<T>>>,
+/// right: Option<Box<TreeNode<T>>>,
+/// }
+///
+/// impl<T> TreeNode<T> {
+/// pub fn traverse_inorder<B>(&self, f: &mut impl FnMut(&T) -> ControlFlow<B>) -> ControlFlow<B> {
+/// if let Some(left) = &self.left {
+/// left.traverse_inorder(f)?;
+/// }
+/// f(&self.value)?;
+/// if let Some(right) = &self.right {
+/// right.traverse_inorder(f)?;
+/// }
+/// ControlFlow::Continue(())
+/// }
+/// fn leaf(value: T) -> Option<Box<TreeNode<T>>> {
+/// Some(Box::new(Self { value, left: None, right: None }))
+/// }
+/// }
+///
+/// let node = TreeNode {
+/// value: 0,
+/// left: TreeNode::leaf(1),
+/// right: Some(Box::new(TreeNode {
+/// value: -1,
+/// left: TreeNode::leaf(5),
+/// right: TreeNode::leaf(2),
+/// }))
+/// };
+/// let mut sum = 0;
+///
+/// let res = node.traverse_inorder(&mut |val| {
+/// if *val < 0 {
+/// ControlFlow::Break(*val)
+/// } else {
+/// sum += *val;
+/// ControlFlow::Continue(())
+/// }
+/// });
+/// assert_eq!(res, ControlFlow::Break(-1));
+/// assert_eq!(sum, 6);
+/// ```
+///
+/// [`Break`]: ControlFlow::Break
+/// [`Continue`]: ControlFlow::Continue
+#[stable(feature = "control_flow_enum_type", since = "1.55.0")]
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum ControlFlow<B, C = ()> {
+ /// Move on to the next phase of the operation as normal.
+ #[stable(feature = "control_flow_enum_type", since = "1.55.0")]
+ #[lang = "Continue"]
+ Continue(C),
+ /// Exit the operation without running subsequent phases.
+ #[stable(feature = "control_flow_enum_type", since = "1.55.0")]
+ #[lang = "Break"]
+ Break(B),
+ // Yes, the order of the variants doesn't match the type parameters.
+ // They're in this order so that `ControlFlow<A, B>` <-> `Result<B, A>`
+ // is a no-op conversion in the `Try` implementation.
+}
+
+#[unstable(feature = "try_trait_v2", issue = "84277")]
+impl<B, C> ops::Try for ControlFlow<B, C> {
+ type Output = C;
+ type Residual = ControlFlow<B, convert::Infallible>;
+
+ #[inline]
+ fn from_output(output: Self::Output) -> Self {
+ ControlFlow::Continue(output)
+ }
+
+ #[inline]
+ fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
+ match self {
+ ControlFlow::Continue(c) => ControlFlow::Continue(c),
+ ControlFlow::Break(b) => ControlFlow::Break(ControlFlow::Break(b)),
+ }
+ }
+}
+
+#[unstable(feature = "try_trait_v2", issue = "84277")]
+impl<B, C> ops::FromResidual for ControlFlow<B, C> {
+ #[inline]
+ fn from_residual(residual: ControlFlow<B, convert::Infallible>) -> Self {
+ match residual {
+ ControlFlow::Break(b) => ControlFlow::Break(b),
+ }
+ }
+}
+
+#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
+impl<B, C> ops::Residual<C> for ControlFlow<B, convert::Infallible> {
+ type TryType = ControlFlow<B, C>;
+}
+
+impl<B, C> ControlFlow<B, C> {
+ /// Returns `true` if this is a `Break` variant.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::ops::ControlFlow;
+ ///
+ /// assert!(ControlFlow::<i32, String>::Break(3).is_break());
+ /// assert!(!ControlFlow::<String, i32>::Continue(3).is_break());
+ /// ```
+ #[inline]
+ #[stable(feature = "control_flow_enum_is", since = "1.59.0")]
+ pub fn is_break(&self) -> bool {
+ matches!(*self, ControlFlow::Break(_))
+ }
+
+ /// Returns `true` if this is a `Continue` variant.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::ops::ControlFlow;
+ ///
+ /// assert!(!ControlFlow::<i32, String>::Break(3).is_continue());
+ /// assert!(ControlFlow::<String, i32>::Continue(3).is_continue());
+ /// ```
+ #[inline]
+ #[stable(feature = "control_flow_enum_is", since = "1.59.0")]
+ pub fn is_continue(&self) -> bool {
+ matches!(*self, ControlFlow::Continue(_))
+ }
+
+ /// Converts the `ControlFlow` into an `Option` which is `Some` if the
+ /// `ControlFlow` was `Break` and `None` otherwise.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(control_flow_enum)]
+ /// use std::ops::ControlFlow;
+ ///
+ /// assert_eq!(ControlFlow::<i32, String>::Break(3).break_value(), Some(3));
+ /// assert_eq!(ControlFlow::<String, i32>::Continue(3).break_value(), None);
+ /// ```
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn break_value(self) -> Option<B> {
+ match self {
+ ControlFlow::Continue(..) => None,
+ ControlFlow::Break(x) => Some(x),
+ }
+ }
+
+ /// Maps `ControlFlow<B, C>` to `ControlFlow<T, C>` by applying a function
+ /// to the break value in case it exists.
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn map_break<T, F>(self, f: F) -> ControlFlow<T, C>
+ where
+ F: FnOnce(B) -> T,
+ {
+ match self {
+ ControlFlow::Continue(x) => ControlFlow::Continue(x),
+ ControlFlow::Break(x) => ControlFlow::Break(f(x)),
+ }
+ }
+
+ /// Converts the `ControlFlow` into an `Option` which is `Some` if the
+ /// `ControlFlow` was `Continue` and `None` otherwise.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(control_flow_enum)]
+ /// use std::ops::ControlFlow;
+ ///
+ /// assert_eq!(ControlFlow::<i32, String>::Break(3).continue_value(), None);
+ /// assert_eq!(ControlFlow::<String, i32>::Continue(3).continue_value(), Some(3));
+ /// ```
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn continue_value(self) -> Option<C> {
+ match self {
+ ControlFlow::Continue(x) => Some(x),
+ ControlFlow::Break(..) => None,
+ }
+ }
+
+ /// Maps `ControlFlow<B, C>` to `ControlFlow<B, T>` by applying a function
+ /// to the continue value in case it exists.
+ #[inline]
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub fn map_continue<T, F>(self, f: F) -> ControlFlow<B, T>
+ where
+ F: FnOnce(C) -> T,
+ {
+ match self {
+ ControlFlow::Continue(x) => ControlFlow::Continue(f(x)),
+ ControlFlow::Break(x) => ControlFlow::Break(x),
+ }
+ }
+}
+
+/// These are used only as part of implementing the iterator adapters.
+/// They have mediocre names and non-obvious semantics, so aren't
+/// currently on a path to potential stabilization.
+impl<R: ops::Try> ControlFlow<R, R::Output> {
+ /// Create a `ControlFlow` from any type implementing `Try`.
+ #[inline]
+ pub(crate) fn from_try(r: R) -> Self {
+ match R::branch(r) {
+ ControlFlow::Continue(v) => ControlFlow::Continue(v),
+ ControlFlow::Break(v) => ControlFlow::Break(R::from_residual(v)),
+ }
+ }
+
+ /// Convert a `ControlFlow` into any type implementing `Try`;
+ #[inline]
+ pub(crate) fn into_try(self) -> R {
+ match self {
+ ControlFlow::Continue(v) => R::from_output(v),
+ ControlFlow::Break(v) => v,
+ }
+ }
+}
+
+impl<B> ControlFlow<B, ()> {
+ /// It's frequently the case that there's no value needed with `Continue`,
+ /// so this provides a way to avoid typing `(())`, if you prefer it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(control_flow_enum)]
+ /// use std::ops::ControlFlow;
+ ///
+ /// let mut partial_sum = 0;
+ /// let last_used = (1..10).chain(20..25).try_for_each(|x| {
+ /// partial_sum += x;
+ /// if partial_sum > 100 { ControlFlow::Break(x) }
+ /// else { ControlFlow::CONTINUE }
+ /// });
+ /// assert_eq!(last_used.break_value(), Some(22));
+ /// ```
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub const CONTINUE: Self = ControlFlow::Continue(());
+}
+
+impl<C> ControlFlow<(), C> {
+ /// APIs like `try_for_each` don't need values with `Break`,
+ /// so this provides a way to avoid typing `(())`, if you prefer it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(control_flow_enum)]
+ /// use std::ops::ControlFlow;
+ ///
+ /// let mut partial_sum = 0;
+ /// (1..10).chain(20..25).try_for_each(|x| {
+ /// if partial_sum > 100 { ControlFlow::BREAK }
+ /// else { partial_sum += x; ControlFlow::CONTINUE }
+ /// });
+ /// assert_eq!(partial_sum, 108);
+ /// ```
+ #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+ pub const BREAK: Self = ControlFlow::Break(());
+}
diff --git a/library/core/src/ops/deref.rs b/library/core/src/ops/deref.rs
new file mode 100644
index 000000000..d68932402
--- /dev/null
+++ b/library/core/src/ops/deref.rs
@@ -0,0 +1,199 @@
+/// 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
+/// [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")]
+#[rustc_diagnostic_item = "Deref"]
+pub trait Deref {
+ /// The resulting type after dereferencing.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_diagnostic_item = "deref_target"]
+ #[lang = "deref_target"]
+ type Target: ?Sized;
+
+ /// Dereferences the value.
+ #[must_use]
+ #[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_diagnostic_item = "deref_method"]
+ fn deref(&self) -> &Self::Target;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<T: ?Sized> const Deref for &T {
+ type Target = T;
+
+ #[rustc_diagnostic_item = "noop_method_deref"]
+ 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")]
+#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
+impl<T: ?Sized> const 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
+/// [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.value);
+/// ```
+#[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 000000000..aa654aa55
--- /dev/null
+++ b/library/core/src/ops/drop.rs
@@ -0,0 +1,165 @@
+/// 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 all the 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 to explicitly call the destructor of a value, [`mem::drop`] can be used instead.
+///
+/// [`mem::drop`]: drop
+///
+/// ## 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.
+#[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 [`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 [`ptr::drop_in_place`].
+ ///
+ /// [E0040]: ../../error-index.html#E0040
+ /// [`panic!`]: crate::panic!
+ /// [`mem::drop`]: drop
+ /// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
+ #[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 000000000..c5a194b7d
--- /dev/null
+++ b/library/core/src/ops/function.rs
@@ -0,0 +1,304 @@
+/// 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
+/// [function pointers]: fn
+/// [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_diagnostic_item = "Fn"]
+#[rustc_paren_sugar]
+#[rustc_on_unimplemented(
+ on(
+ Args = "()",
+ note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
+ ),
+ on(
+ _Self = "unsafe fn",
+ note = "unsafe function cannot be called generically without an unsafe block",
+ // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
+ label = "call the function in a closure: `|| unsafe {{ /* 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
+/// [function pointers]: fn
+/// [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_diagnostic_item = "FnMut"]
+#[rustc_paren_sugar]
+#[rustc_on_unimplemented(
+ on(
+ Args = "()",
+ note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
+ ),
+ on(
+ _Self = "unsafe fn",
+ note = "unsafe function cannot be called generically without an unsafe block",
+ // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
+ label = "call the function in a closure: `|| unsafe {{ /* 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
+/// [function pointers]: fn
+/// [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_diagnostic_item = "FnOnce"]
+#[rustc_paren_sugar]
+#[rustc_on_unimplemented(
+ on(
+ Args = "()",
+ note = "wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`"
+ ),
+ on(
+ _Self = "unsafe fn",
+ note = "unsafe function cannot be called generically without an unsafe block",
+ // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string
+ label = "call the function in a closure: `|| unsafe {{ /* 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 000000000..b651b7b23
--- /dev/null
+++ b/library/core/src/ops/generator.rs
@@ -0,0 +1,136 @@
+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;
+/// "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
+/// [unstable book]: ../../unstable-book/language-features/generators.html
+#[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.
+ #[lang = "generator_return"]
+ 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 000000000..e2e569cb7
--- /dev/null
+++ b/library/core/src/ops/index.rs
@@ -0,0 +1,175 @@
+/// 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`].
+///
+/// # 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.
+ ///
+ /// # Panics
+ ///
+ /// May panic if the index is out of bounds.
+ #[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`.
+///
+/// # 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 {index:?}-side of balance immutably");
+/// 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 {index:?}-side of balance mutably");
+/// 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.
+ ///
+ /// # Panics
+ ///
+ /// May panic if the index is out of bounds.
+ #[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 000000000..31c1a1d09
--- /dev/null
+++ b/library/core/src/ops/mod.rs
@@ -0,0 +1,208 @@
+//! 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 = Self;
+//!
+//! fn add(self, other: Self) -> Self {
+//! Self {x: self.x + other.x, y: self.y + other.y}
+//! }
+//! }
+//!
+//! impl Sub for Point {
+//! type Output = Self;
+//!
+//! fn sub(self, other: Self) -> Self {
+//! Self {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
+//! ```
+//!
+//! [`clone`]: Clone::clone
+//! [operator precedence]: ../../reference/expressions.html#expression-precedence
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+mod arith;
+mod bit;
+mod control_flow;
+mod deref;
+mod drop;
+mod function;
+mod generator;
+mod index;
+mod range;
+mod try_trait;
+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 = "one_sided_range", issue = "69780")]
+pub use self::range::OneSidedRange;
+
+#[unstable(feature = "try_trait_v2", issue = "84277")]
+pub use self::try_trait::{FromResidual, Try};
+
+#[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
+pub use self::try_trait::Yeet;
+
+#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
+pub use self::try_trait::Residual;
+
+pub(crate) use self::try_trait::{ChangeOutputType, NeverShortCircuit};
+
+#[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;
+
+#[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")]
+pub use self::control_flow::ControlFlow;
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
new file mode 100644
index 000000000..a3b148473
--- /dev/null
+++ b/library/core/src/ops/range.rs
@@ -0,0 +1,991 @@
+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]); // This is the `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 ]);
+/// ```
+///
+/// [slicing index]: crate::slice::SliceIndex
+#[lang = "RangeFull"]
+#[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 `start <= x < end`.
+/// It is empty if `start >= end`.
+///
+/// # Examples
+///
+/// The `start..end` syntax is a `Range`:
+///
+/// ```
+/// 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 ]); // This is a `Range`
+/// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
+/// ```
+#[lang = "Range"]
+#[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
+ ///
+ /// ```
+ /// assert!(!(3..5).is_empty());
+ /// assert!( (3..3).is_empty());
+ /// assert!( (3..2).is_empty());
+ /// ```
+ ///
+ /// The range is empty if either side is incomparable:
+ ///
+ /// ```
+ /// assert!(!(3.0..5.0).is_empty());
+ /// assert!( (3.0..f32::NAN).is_empty());
+ /// assert!( (f32::NAN..5.0).is_empty());
+ /// ```
+ #[stable(feature = "range_is_empty", since = "1.47.0")]
+ 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
+///
+/// The `start..` syntax is a `RangeFrom`:
+///
+/// ```
+/// 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]); // This is a `RangeFrom`
+/// assert_eq!(arr[1.. 3], [ 1, 2 ]);
+/// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
+/// ```
+#[lang = "RangeFrom"]
+#[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 ]); // This is a `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 ]);
+/// ```
+///
+/// [slicing index]: crate::slice::SliceIndex
+#[lang = "RangeTo"]
+#[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]: crate::iter::FusedIterator
+/// [`.is_empty()`]: RangeInclusive::is_empty
+///
+/// # Examples
+///
+/// The `start..=end` syntax is a `RangeInclusive`:
+///
+/// ```
+/// 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 ]); // This is a `RangeInclusive`
+/// ```
+#[lang = "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));
+ /// ```
+ #[lang = "range_inclusive_new"]
+ #[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()`]: RangeInclusive::end
+ /// [`is_empty()`]: RangeInclusive::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()`]: RangeInclusive::start
+ /// [`is_empty()`]: RangeInclusive::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)
+ }
+}
+
+impl RangeInclusive<usize> {
+ /// Converts to an exclusive `Range` for `SliceIndex` implementations.
+ /// The caller is responsible for dealing with `end == usize::MAX`.
+ #[inline]
+ pub(crate) const fn into_slice_range(self) -> Range<usize> {
+ // If we're not exhausted, we want to simply slice `start..end + 1`.
+ // If we are exhausted, then slicing with `end + 1..end + 1` gives us an
+ // empty range that is still subject to bounds-checks for that endpoint.
+ let exclusive_end = self.end + 1;
+ let start = if self.exhausted { exclusive_end } else { self.start };
+ start..exclusive_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));
+ /// ```
+ ///
+ /// This method always returns `false` after iteration has finished:
+ ///
+ /// ```
+ /// let mut r = 3..=5;
+ /// assert!(r.contains(&3) && r.contains(&5));
+ /// for _ in r.by_ref() {}
+ /// // Precise field values are unspecified here
+ /// assert!(!r.contains(&3) && !r.contains(&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
+ ///
+ /// ```
+ /// assert!(!(3..=5).is_empty());
+ /// assert!(!(3..=3).is_empty());
+ /// assert!( (3..=2).is_empty());
+ /// ```
+ ///
+ /// The range is empty if either side is incomparable:
+ ///
+ /// ```
+ /// 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:
+ ///
+ /// ```
+ /// let mut r = 3..=5;
+ /// for _ in r.by_ref() {}
+ /// // Precise field values are unspecified here
+ /// assert!(r.is_empty());
+ /// ```
+ #[stable(feature = "range_is_empty", since = "1.47.0")]
+ #[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 ]); // This is a `RangeToInclusive`
+/// assert_eq!(arr[1.. ], [ 1, 2, 3, 4]);
+/// assert_eq!(arr[1.. 3], [ 1, 2 ]);
+/// assert_eq!(arr[1..=3], [ 1, 2, 3 ]);
+/// ```
+///
+/// [slicing index]: crate::slice::SliceIndex
+#[lang = "RangeToInclusive"]
+#[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> Bound<T> {
+ /// Converts from `&Bound<T>` to `Bound<&T>`.
+ #[inline]
+ #[unstable(feature = "bound_as_ref", issue = "80996")]
+ pub fn as_ref(&self) -> Bound<&T> {
+ match *self {
+ Included(ref x) => Included(x),
+ Excluded(ref x) => Excluded(x),
+ Unbounded => Unbounded,
+ }
+ }
+
+ /// Converts from `&mut Bound<T>` to `Bound<&mut T>`.
+ #[inline]
+ #[unstable(feature = "bound_as_ref", issue = "80996")]
+ pub fn as_mut(&mut self) -> Bound<&mut T> {
+ match *self {
+ Included(ref mut x) => Included(x),
+ Excluded(ref mut x) => Excluded(x),
+ Unbounded => Unbounded,
+ }
+ }
+
+ /// Maps a `Bound<T>` to a `Bound<U>` by applying a function to the contained value (including
+ /// both `Included` and `Excluded`), returning a `Bound` of the same kind.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(bound_map)]
+ /// use std::ops::Bound::*;
+ ///
+ /// let bound_string = Included("Hello, World!");
+ ///
+ /// assert_eq!(bound_string.map(|s| s.len()), Included(13));
+ /// ```
+ ///
+ /// ```
+ /// #![feature(bound_map)]
+ /// use std::ops::Bound;
+ /// use Bound::*;
+ ///
+ /// let unbounded_string: Bound<String> = Unbounded;
+ ///
+ /// assert_eq!(unbounded_string.map(|s| s.len()), Unbounded);
+ /// ```
+ #[inline]
+ #[unstable(feature = "bound_map", issue = "86026")]
+ pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U> {
+ match self {
+ Unbounded => Unbounded,
+ Included(x) => Included(f(x)),
+ Excluded(x) => Excluded(f(x)),
+ }
+ }
+}
+
+impl<T: Clone> Bound<&T> {
+ /// Map a `Bound<&T>` to a `Bound<T>` by cloning the contents of the bound.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// 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));
+ /// ```
+ #[must_use = "`self` will be dropped if the result is not used"]
+ #[stable(feature = "bound_cloned", since = "1.55.0")]
+ 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()),
+ }
+ }
+}
+
+/// `RangeBounds` is implemented by Rust's built-in range types, produced
+/// by range syntax like `..`, `a..`, `..b`, `..=c`, `d..e`, or `f..=g`.
+#[stable(feature = "collections_range", since = "1.28.0")]
+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(start) => start <= item,
+ Excluded(start) => start < item,
+ Unbounded => true,
+ }) && (match self.end_bound() {
+ Included(end) => item <= end,
+ Excluded(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> {
+ if self.exhausted {
+ // When the iterator is exhausted, we usually have start == end,
+ // but we want the range to appear empty, containing nothing.
+ Excluded(&self.end)
+ } else {
+ 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)
+ }
+}
+
+/// `OneSidedRange` is implemented for built-in range types that are unbounded
+/// on one side. For example, `a..`, `..b` and `..=c` implement `OneSidedRange`,
+/// but `..`, `d..e`, and `f..=g` do not.
+///
+/// Types that implement `OneSidedRange<T>` must return `Bound::Unbounded`
+/// from one of `RangeBounds::start_bound` or `RangeBounds::end_bound`.
+#[unstable(feature = "one_sided_range", issue = "69780")]
+pub trait OneSidedRange<T: ?Sized>: RangeBounds<T> {}
+
+#[unstable(feature = "one_sided_range", issue = "69780")]
+impl<T> OneSidedRange<T> for RangeTo<T> where Self: RangeBounds<T> {}
+
+#[unstable(feature = "one_sided_range", issue = "69780")]
+impl<T> OneSidedRange<T> for RangeFrom<T> where Self: RangeBounds<T> {}
+
+#[unstable(feature = "one_sided_range", issue = "69780")]
+impl<T> OneSidedRange<T> for RangeToInclusive<T> where Self: RangeBounds<T> {}
diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs
new file mode 100644
index 000000000..02f7f62bf
--- /dev/null
+++ b/library/core/src/ops/try_trait.rs
@@ -0,0 +1,418 @@
+use crate::ops::ControlFlow;
+
+/// The `?` operator and `try {}` blocks.
+///
+/// `try_*` methods typically involve a type implementing this trait. For
+/// example, the closures passed to [`Iterator::try_fold`] and
+/// [`Iterator::try_for_each`] must return such a type.
+///
+/// `Try` types are typically those containing two or more categories of values,
+/// some subset of which are so commonly handled via early returns that it's
+/// worth providing a terse (but still visible) syntax to make that easy.
+///
+/// This is most often seen for error handling with [`Result`] and [`Option`].
+/// The quintessential implementation of this trait is on [`ControlFlow`].
+///
+/// # Using `Try` in Generic Code
+///
+/// `Iterator::try_fold` was stabilized to call back in Rust 1.27, but
+/// this trait is much newer. To illustrate the various associated types and
+/// methods, let's implement our own version.
+///
+/// As a reminder, an infallible version of a fold looks something like this:
+/// ```
+/// fn simple_fold<A, T>(
+/// iter: impl Iterator<Item = T>,
+/// mut accum: A,
+/// mut f: impl FnMut(A, T) -> A,
+/// ) -> A {
+/// for x in iter {
+/// accum = f(accum, x);
+/// }
+/// accum
+/// }
+/// ```
+///
+/// So instead of `f` returning just an `A`, we'll need it to return some other
+/// type that produces an `A` in the "don't short circuit" path. Conveniently,
+/// that's also the type we need to return from the function.
+///
+/// Let's add a new generic parameter `R` for that type, and bound it to the
+/// output type that we want:
+/// ```
+/// # #![feature(try_trait_v2)]
+/// # use std::ops::Try;
+/// fn simple_try_fold_1<A, T, R: Try<Output = A>>(
+/// iter: impl Iterator<Item = T>,
+/// mut accum: A,
+/// mut f: impl FnMut(A, T) -> R,
+/// ) -> R {
+/// todo!()
+/// }
+/// ```
+///
+/// If we get through the entire iterator, we need to wrap up the accumulator
+/// into the return type using [`Try::from_output`]:
+/// ```
+/// # #![feature(try_trait_v2)]
+/// # use std::ops::{ControlFlow, Try};
+/// fn simple_try_fold_2<A, T, R: Try<Output = A>>(
+/// iter: impl Iterator<Item = T>,
+/// mut accum: A,
+/// mut f: impl FnMut(A, T) -> R,
+/// ) -> R {
+/// for x in iter {
+/// let cf = f(accum, x).branch();
+/// match cf {
+/// ControlFlow::Continue(a) => accum = a,
+/// ControlFlow::Break(_) => todo!(),
+/// }
+/// }
+/// R::from_output(accum)
+/// }
+/// ```
+///
+/// We'll also need [`FromResidual::from_residual`] to turn the residual back
+/// into the original type. But because it's a supertrait of `Try`, we don't
+/// need to mention it in the bounds. All types which implement `Try` can be
+/// recreated from their corresponding residual, so we'll just call it:
+/// ```
+/// # #![feature(try_trait_v2)]
+/// # use std::ops::{ControlFlow, Try};
+/// pub fn simple_try_fold_3<A, T, R: Try<Output = A>>(
+/// iter: impl Iterator<Item = T>,
+/// mut accum: A,
+/// mut f: impl FnMut(A, T) -> R,
+/// ) -> R {
+/// for x in iter {
+/// let cf = f(accum, x).branch();
+/// match cf {
+/// ControlFlow::Continue(a) => accum = a,
+/// ControlFlow::Break(r) => return R::from_residual(r),
+/// }
+/// }
+/// R::from_output(accum)
+/// }
+/// ```
+///
+/// But this "call `branch`, then `match` on it, and `return` if it was a
+/// `Break`" is exactly what happens inside the `?` operator. So rather than
+/// do all this manually, we can just use `?` instead:
+/// ```
+/// # #![feature(try_trait_v2)]
+/// # use std::ops::Try;
+/// fn simple_try_fold<A, T, R: Try<Output = A>>(
+/// iter: impl Iterator<Item = T>,
+/// mut accum: A,
+/// mut f: impl FnMut(A, T) -> R,
+/// ) -> R {
+/// for x in iter {
+/// accum = f(accum, x)?;
+/// }
+/// R::from_output(accum)
+/// }
+/// ```
+#[unstable(feature = "try_trait_v2", issue = "84277")]
+#[rustc_on_unimplemented(
+ on(
+ all(from_desugaring = "TryBlock"),
+ message = "a `try` block must return `Result` or `Option` \
+ (or another type that implements `{Try}`)",
+ label = "could not wrap the final value of the block as `{Self}` doesn't implement `Try`",
+ ),
+ on(
+ all(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: FromResidual {
+ /// The type of the value produced by `?` when *not* short-circuiting.
+ #[unstable(feature = "try_trait_v2", issue = "84277")]
+ type Output;
+
+ /// The type of the value passed to [`FromResidual::from_residual`]
+ /// as part of `?` when short-circuiting.
+ ///
+ /// This represents the possible values of the `Self` type which are *not*
+ /// represented by the `Output` type.
+ ///
+ /// # Note to Implementors
+ ///
+ /// The choice of this type is critical to interconversion.
+ /// Unlike the `Output` type, which will often be a raw generic type,
+ /// this type is typically a newtype of some sort to "color" the type
+ /// so that it's distinguishable from the residuals of other types.
+ ///
+ /// This is why `Result<T, E>::Residual` is not `E`, but `Result<Infallible, E>`.
+ /// That way it's distinct from `ControlFlow<E>::Residual`, for example,
+ /// and thus `?` on `ControlFlow` cannot be used in a method returning `Result`.
+ ///
+ /// If you're making a generic type `Foo<T>` that implements `Try<Output = T>`,
+ /// then typically you can use `Foo<std::convert::Infallible>` as its `Residual`
+ /// type: that type will have a "hole" in the correct place, and will maintain the
+ /// "foo-ness" of the residual so other types need to opt-in to interconversion.
+ #[unstable(feature = "try_trait_v2", issue = "84277")]
+ type Residual;
+
+ /// Constructs the type from its `Output` type.
+ ///
+ /// This should be implemented consistently with the `branch` method
+ /// such that applying the `?` operator will get back the original value:
+ /// `Try::from_output(x).branch() --> ControlFlow::Continue(x)`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(try_trait_v2)]
+ /// use std::ops::Try;
+ ///
+ /// assert_eq!(<Result<_, String> as Try>::from_output(3), Ok(3));
+ /// assert_eq!(<Option<_> as Try>::from_output(4), Some(4));
+ /// assert_eq!(
+ /// <std::ops::ControlFlow<String, _> as Try>::from_output(5),
+ /// std::ops::ControlFlow::Continue(5),
+ /// );
+ ///
+ /// # fn make_question_mark_work() -> Option<()> {
+ /// assert_eq!(Option::from_output(4)?, 4);
+ /// # None }
+ /// # make_question_mark_work();
+ ///
+ /// // This is used, for example, on the accumulator in `try_fold`:
+ /// let r = std::iter::empty().try_fold(4, |_, ()| -> Option<_> { unreachable!() });
+ /// assert_eq!(r, Some(4));
+ /// ```
+ #[lang = "from_output"]
+ #[unstable(feature = "try_trait_v2", issue = "84277")]
+ fn from_output(output: Self::Output) -> Self;
+
+ /// Used in `?` to decide whether the operator should produce a value
+ /// (because this returned [`ControlFlow::Continue`])
+ /// or propagate a value back to the caller
+ /// (because this returned [`ControlFlow::Break`]).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(try_trait_v2)]
+ /// use std::ops::{ControlFlow, Try};
+ ///
+ /// assert_eq!(Ok::<_, String>(3).branch(), ControlFlow::Continue(3));
+ /// assert_eq!(Err::<String, _>(3).branch(), ControlFlow::Break(Err(3)));
+ ///
+ /// assert_eq!(Some(3).branch(), ControlFlow::Continue(3));
+ /// assert_eq!(None::<String>.branch(), ControlFlow::Break(None));
+ ///
+ /// assert_eq!(ControlFlow::<String, _>::Continue(3).branch(), ControlFlow::Continue(3));
+ /// assert_eq!(
+ /// ControlFlow::<_, String>::Break(3).branch(),
+ /// ControlFlow::Break(ControlFlow::Break(3)),
+ /// );
+ /// ```
+ #[lang = "branch"]
+ #[unstable(feature = "try_trait_v2", issue = "84277")]
+ fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+}
+
+/// Used to specify which residuals can be converted into which [`crate::ops::Try`] types.
+///
+/// Every `Try` type needs to be recreatable from its own associated
+/// `Residual` type, but can also have additional `FromResidual` implementations
+/// to support interconversion with other `Try` types.
+#[rustc_on_unimplemented(
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::result::Result<T, E>",
+ R = "std::option::Option<std::convert::Infallible>"
+ ),
+ message = "the `?` operator can only be used on `Result`s, not `Option`s, \
+ in {ItemContext} that returns `Result`",
+ label = "use `.ok_or(...)?` to provide an error compatible with `{Self}`",
+ enclosing_scope = "this function returns a `Result`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::result::Result<T, E>",
+ ),
+ // There's a special error message in the trait selection code for
+ // `From` in `?`, so this is not shown for result-in-result errors,
+ // and thus it can be phrased more strongly than `ControlFlow`'s.
+ message = "the `?` operator can only be used on `Result`s \
+ in {ItemContext} that returns `Result`",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ enclosing_scope = "this function returns a `Result`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::option::Option<T>",
+ R = "std::result::Result<T, E>",
+ ),
+ message = "the `?` operator can only be used on `Option`s, not `Result`s, \
+ in {ItemContext} that returns `Option`",
+ label = "use `.ok()?` if you want to discard the `{R}` error information",
+ enclosing_scope = "this function returns an `Option`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::option::Option<T>",
+ ),
+ // `Option`-in-`Option` always works, as there's only one possible
+ // residual, so this can also be phrased strongly.
+ message = "the `?` operator can only be used on `Option`s \
+ in {ItemContext} that returns `Option`",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ enclosing_scope = "this function returns an `Option`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::ops::ControlFlow<B, C>",
+ R = "std::ops::ControlFlow<B, C>",
+ ),
+ message = "the `?` operator in {ItemContext} that returns `ControlFlow<B, _>` \
+ can only be used on other `ControlFlow<B, _>`s (with the same Break type)",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ enclosing_scope = "this function returns a `ControlFlow`",
+ note = "unlike `Result`, there's no `From`-conversion performed for `ControlFlow`"
+ ),
+ on(
+ all(
+ from_desugaring = "QuestionMark",
+ _Self = "std::ops::ControlFlow<B, C>",
+ // `R` is not a `ControlFlow`, as that case was matched previously
+ ),
+ message = "the `?` operator can only be used on `ControlFlow`s \
+ in {ItemContext} that returns `ControlFlow`",
+ label = "this `?` produces `{R}`, which is incompatible with `{Self}`",
+ enclosing_scope = "this function returns a `ControlFlow`",
+ ),
+ on(
+ all(from_desugaring = "QuestionMark"),
+ message = "the `?` operator can only be used in {ItemContext} \
+ that returns `Result` or `Option` \
+ (or another type that implements `{FromResidual}`)",
+ label = "cannot use the `?` operator in {ItemContext} that returns `{Self}`",
+ enclosing_scope = "this function should return `Result` or `Option` to accept `?`"
+ ),
+)]
+#[rustc_diagnostic_item = "FromResidual"]
+#[unstable(feature = "try_trait_v2", issue = "84277")]
+pub trait FromResidual<R = <Self as Try>::Residual> {
+ /// Constructs the type from a compatible `Residual` type.
+ ///
+ /// This should be implemented consistently with the `branch` method such
+ /// that applying the `?` operator will get back an equivalent residual:
+ /// `FromResidual::from_residual(r).branch() --> ControlFlow::Break(r)`.
+ /// (It must not be an *identical* residual when interconversion is involved.)
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(try_trait_v2)]
+ /// use std::ops::{ControlFlow, FromResidual};
+ ///
+ /// assert_eq!(Result::<String, i64>::from_residual(Err(3_u8)), Err(3));
+ /// assert_eq!(Option::<String>::from_residual(None), None);
+ /// assert_eq!(
+ /// ControlFlow::<_, String>::from_residual(ControlFlow::Break(5)),
+ /// ControlFlow::Break(5),
+ /// );
+ /// ```
+ #[lang = "from_residual"]
+ #[unstable(feature = "try_trait_v2", issue = "84277")]
+ fn from_residual(residual: R) -> Self;
+}
+
+#[unstable(
+ feature = "yeet_desugar_details",
+ issue = "none",
+ reason = "just here to simplify the desugaring; will never be stabilized"
+)]
+#[inline]
+#[track_caller] // because `Result::from_residual` has it
+#[lang = "from_yeet"]
+pub fn from_yeet<T, Y>(yeeted: Y) -> T
+where
+ T: FromResidual<Yeet<Y>>,
+{
+ FromResidual::from_residual(Yeet(yeeted))
+}
+
+/// Allows retrieving the canonical type implementing [`Try`] that has this type
+/// as its residual and allows it to hold an `O` as its output.
+///
+/// If you think of the `Try` trait as splitting a type into its [`Try::Output`]
+/// and [`Try::Residual`] components, this allows putting them back together.
+///
+/// For example,
+/// `Result<T, E>: Try<Output = T, Residual = Result<Infallible, E>>`,
+/// and in the other direction,
+/// `<Result<Infallible, E> as Residual<T>>::TryType = Result<T, E>`.
+#[unstable(feature = "try_trait_v2_residual", issue = "91285")]
+pub trait Residual<O> {
+ /// The "return" type of this meta-function.
+ #[unstable(feature = "try_trait_v2_residual", issue = "91285")]
+ type TryType: Try<Output = O, Residual = Self>;
+}
+
+#[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")]
+pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::TryType;
+
+/// An adapter for implementing non-try methods via the `Try` implementation.
+///
+/// Conceptually the same as `Result<T, !>`, but requiring less work in trait
+/// solving and inhabited-ness checking and such, by being an obvious newtype
+/// and not having `From` bounds lying around.
+///
+/// Not currently planned to be exposed publicly, so just `pub(crate)`.
+#[repr(transparent)]
+pub(crate) struct NeverShortCircuit<T>(pub T);
+
+impl<T> NeverShortCircuit<T> {
+ /// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`.
+ #[inline]
+ pub fn wrap_mut_2<A, B>(mut f: impl FnMut(A, B) -> T) -> impl FnMut(A, B) -> Self {
+ move |a, b| NeverShortCircuit(f(a, b))
+ }
+}
+
+pub(crate) enum NeverShortCircuitResidual {}
+
+impl<T> Try for NeverShortCircuit<T> {
+ type Output = T;
+ type Residual = NeverShortCircuitResidual;
+
+ #[inline]
+ fn branch(self) -> ControlFlow<NeverShortCircuitResidual, T> {
+ ControlFlow::Continue(self.0)
+ }
+
+ #[inline]
+ fn from_output(x: T) -> Self {
+ NeverShortCircuit(x)
+ }
+}
+
+impl<T> FromResidual for NeverShortCircuit<T> {
+ #[inline]
+ fn from_residual(never: NeverShortCircuitResidual) -> Self {
+ match never {}
+ }
+}
+
+impl<T> Residual<T> for NeverShortCircuitResidual {
+ type TryType = NeverShortCircuit<T>;
+}
+
+/// Implement `FromResidual<Yeet<T>>` on your type to enable
+/// `do yeet expr` syntax in functions returning your type.
+#[unstable(feature = "try_trait_v2_yeet", issue = "96374")]
+#[derive(Debug)]
+pub struct Yeet<T>(pub T);
diff --git a/library/core/src/ops/unsize.rs b/library/core/src/ops/unsize.rs
new file mode 100644
index 000000000..a920b9165
--- /dev/null
+++ b/library/core/src/ops/unsize.rs
@@ -0,0 +1,132 @@
+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]: crate::marker::Unsize
+/// [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 {}
+
+/// `DispatchFromDyn` is used in the implementation of object safety checks (specifically allowing
+/// arbitrary self types), to guarantee that a method's receiver type can be dispatched on.
+///
+/// Note: `DispatchFromDyn` was briefly named `CoerceSized` (and had a slightly different
+/// interpretation).
+///
+/// Imagine we have a trait object `t` with type `&dyn Tr`, where `Tr` is some trait with a method
+/// `m` defined as `fn m(&self);`. When calling `t.m()`, the receiver `t` is a wide pointer, but an
+/// implementation of `m` will expect a narrow pointer as `&self` (a reference to the concrete
+/// type). The compiler must generate an implicit conversion from the trait object/wide pointer to
+/// the concrete reference/narrow pointer. Implementing `DispatchFromDyn` indicates that that
+/// conversion is allowed and thus that the type implementing `DispatchFromDyn` is safe to use as
+/// the self type in an object-safe method. (in the above example, the compiler will require
+/// `DispatchFromDyn` is implemented for `&'a U`).
+///
+/// `DispatchFromDyn` does not specify the conversion from wide pointer to narrow pointer; the
+/// conversion is hard-wired into the compiler. For the conversion to work, the following
+/// properties must hold (i.e., it is only safe to implement `DispatchFromDyn` for types which have
+/// these properties, these are also checked by the compiler):
+///
+/// * EITHER `Self` and `T` are either both references or both raw pointers; in either case, with
+/// the same mutability.
+/// * OR, all of the following hold
+/// - `Self` and `T` must have the same type constructor, and only vary in a single type parameter
+/// formal (the *coerced type*, e.g., `impl DispatchFromDyn<Rc<T>> for Rc<U>` is ok and the
+/// single type parameter (instantiated with `T` or `U`) is the coerced type,
+/// `impl DispatchFromDyn<Arc<T>> for Rc<U>` is not ok).
+/// - The definition for `Self` must be a struct.
+/// - The definition for `Self` must not be `#[repr(packed)]` or `#[repr(C)]`.
+/// - Other than one-aligned, zero-sized fields, the definition for `Self` must have exactly one
+/// field and that field's type must be the coerced type. Furthermore, `Self`'s field type must
+/// implement `DispatchFromDyn<F>` where `F` is the type of `T`'s field type.
+///
+/// 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 {}