diff options
| author | bors <bors@rust-lang.org> | 2020-07-27 17:39:01 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-07-27 17:39:01 +0000 |
| commit | 54e000891ffccd4cbfb92146b92736c83085df63 (patch) | |
| tree | 1200bb13eb9ae22def4c43bc657bc56da8faedc6 /src/libcore/ops | |
| parent | 4a90e36c85336d1d4b209556c1a9733210bbff19 (diff) | |
| parent | 6d9705220fec4553d693a7c19d99496e14c89edf (diff) | |
| download | rust-tmp-nightly.tar.gz | |
Auto merge of #73265 - mark-i-m:mv-std, r=<try>tmp-nightly
mv std libs to library/
This is the first step in refactoring the directory layout of this repository, with further followup steps planned (but not done yet).
Background: currently, all crates are under src/, without nested src directories and with the unconventional `lib*` prefixes (e.g., `src/libcore/lib.rs`). This directory structures is not idiomatic and makes the `src/` directory rather overwhelming. To improve contributor experience and make things a bit more approachable, we are reorganizing the repo a bit.
In this PR, we move the standard libs (basically anything that is "runtime", as opposed to part of the compiler, build system, or one of the tools, etc). The new layout moves these libraries to a new `library/` directory in the root of the repo. Additionally, we remove the `lib*` prefixes and add nested `src/` directories. The other crates/tools in this repo are not touched. So in summary:
```
library/<crate>/src/*.rs
src/<all the rest> // unchanged
```
where `<crate>` is:
- core
- alloc
- std
- test
- proc_macro
- panic_abort
- panic_unwind
- profiler_builtins
- term
- unwind
- rtstartup
- backtrace
- rustc-std-workspace-*
There was a lot of discussion about this and a few rounds of compiler team approvals, FCPs, MCPs, and nominations. The original MCP is https://github.com/rust-lang/compiler-team/issues/298. The final approval of the compiler team was given here: https://github.com/rust-lang/rust/pull/73265#issuecomment-659498446.
The name `library` was chosen to complement a later move of the compiler crates to a `compiler/` directory. There was a lot of discussion around adding the nested `src/` directories. Note that this does increase the nesting depth (plausibly important for manual traversal of the tree, e.g., through GitHub's UI or `cd`), but this is deemed to be better as it fits the standard layout of Rust crates throughout most of the ecosystem, though there is some debate about how much this should apply to multi-crate projects. Overall, there seem to be more people in favor of nested `src/` than against.
After this PR, there are no dependencies out of the `library/` directory except on the `build_helper` (or crates.io crates).
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 {} |
