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