]> git.lizzy.rs Git - rust.git/blobdiff - src/libcore/ops.rs
Auto merge of #23934 - lfairy:write-no-deref, r=alexcrichton
[rust.git] / src / libcore / ops.rs
index 4116d8be9fb5c034dddf16bf96a088c7745870ca..faf305c6a13783e6965aaf061d5f46ffb8030790 100644 (file)
@@ -27,7 +27,7 @@
 //! idea to have both `T` and `&T` implement the traits `Add<T>` and `Add<&T>`
 //! so that generic code can be written without unnecessary cloning.
 //!
-//! # Example
+//! # Examples
 //!
 //! This example creates a `Point` struct that implements `Add` and `Sub`, and then
 //! demonstrates adding and subtracting two `Point`s.
 /// The `Drop` trait is used to run some code when a value goes out of scope. This
 /// is sometimes called a 'destructor'.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Drop`. The `drop` method is called when `_x` goes
 /// out of scope, and therefore `main` prints `Dropping!`.
 ///
-/// ```rust
+/// ```
 /// struct HasDrop;
 ///
 /// impl Drop for HasDrop {
@@ -157,15 +157,15 @@ fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
 
 /// The `Add` trait is used to specify the functionality of `+`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Add`. When `Foo + Foo` happens, it ends up
 /// calling `add`, and therefore, `main` prints `Adding!`.
 ///
-/// ```rust
+/// ```
 /// use std::ops::Add;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Add for Foo {
@@ -211,15 +211,15 @@ fn add(self, other: $t) -> $t { self + other }
 
 /// The `Sub` trait is used to specify the functionality of `-`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Sub`. When `Foo - Foo` happens, it ends up
 /// calling `sub`, and therefore, `main` prints `Subtracting!`.
 ///
-/// ```rust
+/// ```
 /// use std::ops::Sub;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Sub for Foo {
@@ -265,15 +265,15 @@ fn sub(self, other: $t) -> $t { self - other }
 
 /// The `Mul` trait is used to specify the functionality of `*`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Mul`. When `Foo * Foo` happens, it ends up
 /// calling `mul`, and therefore, `main` prints `Multiplying!`.
 ///
-/// ```rust
+/// ```
 /// use std::ops::Mul;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Mul for Foo {
@@ -319,7 +319,7 @@ fn mul(self, other: $t) -> $t { self * other }
 
 /// The `Div` trait is used to specify the functionality of `/`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Div`. When `Foo / Foo` happens, it ends up
 /// calling `div`, and therefore, `main` prints `Dividing!`.
@@ -327,7 +327,7 @@ fn mul(self, other: $t) -> $t { self * other }
 /// ```
 /// use std::ops::Div;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Div for Foo {
@@ -373,7 +373,7 @@ fn div(self, other: $t) -> $t { self / other }
 
 /// The `Rem` trait is used to specify the functionality of `%`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Rem`. When `Foo % Foo` happens, it ends up
 /// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
@@ -381,7 +381,7 @@ fn div(self, other: $t) -> $t { self / other }
 /// ```
 /// use std::ops::Rem;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Rem for Foo {
@@ -446,7 +446,7 @@ fn rem(self, other: $t) -> $t {
 
 /// The `Neg` trait is used to specify the functionality of unary `-`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Neg`. When `-Foo` happens, it ends up calling
 /// `neg`, and therefore, `main` prints `Negating!`.
@@ -454,7 +454,7 @@ fn rem(self, other: $t) -> $t {
 /// ```
 /// use std::ops::Neg;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Neg for Foo {
@@ -482,48 +482,44 @@ pub trait Neg {
     fn neg(self) -> Self::Output;
 }
 
-macro_rules! neg_impl {
-    ($($t:ty)*) => ($(
+
+
+macro_rules! neg_impl_core {
+    ($id:ident => $body:expr, $($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
+        #[allow(unsigned_negation)]
         impl Neg for $t {
             #[stable(feature = "rust1", since = "1.0.0")]
             type Output = $t;
 
             #[inline]
             #[stable(feature = "rust1", since = "1.0.0")]
-            fn neg(self) -> $t { -self }
+            fn neg(self) -> $t { let $id = self; $body }
         }
 
         forward_ref_unop! { impl Neg, neg for $t }
     )*)
 }
 
-macro_rules! neg_uint_impl {
-    ($t:ty, $t_signed:ty) => {
-        #[stable(feature = "rust1", since = "1.0.0")]
-        impl Neg for $t {
-            type Output = $t;
-
-            #[inline]
-            fn neg(self) -> $t { -(self as $t_signed) as $t }
-        }
-
-        forward_ref_unop! { impl Neg, neg for $t }
-    }
+macro_rules! neg_impl_numeric {
+    ($($t:ty)*) => { neg_impl_core!{ x => -x, $($t)*} }
 }
 
-neg_impl! { isize i8 i16 i32 i64 f32 f64 }
-
-neg_uint_impl! { usize, isize }
-neg_uint_impl! { u8, i8 }
-neg_uint_impl! { u16, i16 }
-neg_uint_impl! { u32, i32 }
-neg_uint_impl! { u64, i64 }
+macro_rules! neg_impl_unsigned {
+    ($($t:ty)*) => {
+        neg_impl_core!{ x => {
+            #[cfg(stage0)]
+            use ::num::wrapping::WrappingOps;
+            !x.wrapping_add(1)
+        }, $($t)*} }
+}
 
+// neg_impl_unsigned! { usize u8 u16 u32 u64 }
+neg_impl_numeric! { isize i8 i16 i32 i64 f32 f64 }
 
 /// The `Not` trait is used to specify the functionality of unary `!`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Not`. When `!Foo` happens, it ends up calling
 /// `not`, and therefore, `main` prints `Not-ing!`.
@@ -531,7 +527,7 @@ fn neg(self) -> $t { -(self as $t_signed) as $t }
 /// ```
 /// use std::ops::Not;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Not for Foo {
@@ -577,7 +573,7 @@ fn not(self) -> $t { !self }
 
 /// The `BitAnd` trait is used to specify the functionality of `&`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `BitAnd`. When `Foo & Foo` happens, it ends up
 /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
@@ -585,7 +581,7 @@ fn not(self) -> $t { !self }
 /// ```
 /// use std::ops::BitAnd;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitAnd for Foo {
@@ -631,7 +627,7 @@ fn bitand(self, rhs: $t) -> $t { self & rhs }
 
 /// The `BitOr` trait is used to specify the functionality of `|`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `BitOr`. When `Foo | Foo` happens, it ends up
 /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
@@ -639,7 +635,7 @@ fn bitand(self, rhs: $t) -> $t { self & rhs }
 /// ```
 /// use std::ops::BitOr;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitOr for Foo {
@@ -685,7 +681,7 @@ fn bitor(self, rhs: $t) -> $t { self | rhs }
 
 /// The `BitXor` trait is used to specify the functionality of `^`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `BitXor`. When `Foo ^ Foo` happens, it ends up
 /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
@@ -693,7 +689,7 @@ fn bitor(self, rhs: $t) -> $t { self | rhs }
 /// ```
 /// use std::ops::BitXor;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitXor for Foo {
@@ -739,7 +735,7 @@ fn bitxor(self, other: $t) -> $t { self ^ other }
 
 /// The `Shl` trait is used to specify the functionality of `<<`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Shl`. When `Foo << Foo` happens, it ends up
 /// calling `shl`, and therefore, `main` prints `Shifting left!`.
@@ -747,7 +743,7 @@ fn bitxor(self, other: $t) -> $t { self ^ other }
 /// ```
 /// use std::ops::Shl;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Shl<Foo> for Foo {
@@ -811,7 +807,7 @@ macro_rules! shl_impl_all {
 
 /// The `Shr` trait is used to specify the functionality of `>>`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Shr`. When `Foo >> Foo` happens, it ends up
 /// calling `shr`, and therefore, `main` prints `Shifting right!`.
@@ -819,7 +815,7 @@ macro_rules! shl_impl_all {
 /// ```
 /// use std::ops::Shr;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Shr<Foo> for Foo {
@@ -883,7 +879,7 @@ macro_rules! shr_impl_all {
 /// The `Index` trait is used to specify the functionality of indexing operations
 /// like `arr[idx]` when used in an immutable context.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `Index`. When `Foo[Bar]` happens, it ends up
 /// calling `index`, and therefore, `main` prints `Indexing!`.
@@ -891,14 +887,14 @@ macro_rules! shr_impl_all {
 /// ```
 /// use std::ops::Index;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -918,13 +914,13 @@ pub trait Index<Idx: ?Sized> {
 
     /// The method for the indexing (`Foo[Bar]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
+    fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
 }
 
 /// The `IndexMut` trait is used to specify the functionality of indexing
 /// operations like `arr[idx]`, when used in a mutable context.
 ///
-/// # Example
+/// # Examples
 ///
 /// A trivial implementation of `IndexMut`. When `Foo[Bar]` happens, it ends up
 /// calling `index_mut`, and therefore, `main` prints `Indexing!`.
@@ -932,20 +928,20 @@ pub trait Index<Idx: ?Sized> {
 /// ```
 /// use std::ops::{Index, IndexMut};
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
 /// impl Index<Bar> for Foo {
 ///     type Output = Foo;
 ///
-///     fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
+///     fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
 ///         self
 ///     }
 /// }
 ///
 /// impl IndexMut<Bar> for Foo {
-///     fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
+///     fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
 ///         println!("Indexing!");
 ///         self
 ///     }
@@ -961,7 +957,7 @@ pub trait Index<Idx: ?Sized> {
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// The method for the indexing (`Foo[Bar]`) operation
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
+    fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
 }
 
 /// An unbounded range.
@@ -983,8 +979,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 #[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,
 }
 
@@ -1001,11 +999,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 #[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 {
@@ -1019,6 +1016,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 #[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,
 }
 
@@ -1029,11 +1027,10 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-
 /// The `Deref` trait is used to specify the functionality of dereferencing
 /// operations like `*v`.
 ///
-/// # Example
+/// # Examples
 ///
 /// A struct with a single field which is accessible via dereferencing the
 /// struct.
@@ -1087,7 +1084,7 @@ fn deref(&self) -> &T { *self }
 /// The `DerefMut` trait is used to specify the functionality of dereferencing
 /// mutably like `*v = 1;`
 ///
-/// # Example
+/// # Examples
 ///
 /// A struct with a single field which is modifiable via dereferencing the
 /// struct.
@@ -1136,10 +1133,8 @@ fn deref_mut(&mut self) -> &mut T { *self }
 #[lang="fn"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
-pub trait Fn<Args> {
-    /// The returned type after the call operator is used.
-    type Output;
-
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+pub trait Fn<Args> : FnMut<Args> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call(&self, args: Args) -> Self::Output;
 }
@@ -1148,10 +1143,8 @@ pub trait Fn<Args> {
 #[lang="fn_mut"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
-pub trait FnMut<Args> {
-    /// The returned type after the call operator is used.
-    type Output;
-
+#[fundamental] // so that regex can rely that `&str: !FnMut`
+pub trait FnMut<Args> : FnOnce<Args> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
 }
@@ -1160,6 +1153,7 @@ pub trait FnMut<Args> {
 #[lang="fn_once"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
+#[fundamental] // so that regex can rely that `&str: !FnMut`
 pub trait FnOnce<Args> {
     /// The returned type after the call operator is used.
     type Output;
@@ -1168,22 +1162,51 @@ pub trait FnOnce<Args> {
     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
 }
 
-impl<F: ?Sized, A> FnMut<A> for F
-    where F : Fn<A>
-{
-    type Output = <F as Fn<A>>::Output;
+#[cfg(not(stage0))]
+mod impls {
+    use marker::Sized;
+    use super::{Fn, FnMut, FnOnce};
 
-    extern "rust-call" fn call_mut(&mut self, args: A) -> <F as Fn<A>>::Output {
-        self.call(args)
+    impl<'a,A,F:?Sized> Fn<A> for &'a F
+        where F : Fn<A>
+    {
+        extern "rust-call" fn call(&self, args: A) -> F::Output {
+            (**self).call(args)
+        }
     }
-}
 
-impl<F,A> FnOnce<A> for F
-    where F : FnMut<A>
-{
-    type Output = <F as FnMut<A>>::Output;
+    impl<'a,A,F:?Sized> FnMut<A> for &'a F
+        where F : Fn<A>
+    {
+        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
+            (**self).call(args)
+        }
+    }
+
+    impl<'a,A,F:?Sized> FnOnce<A> for &'a F
+        where F : Fn<A>
+    {
+        type Output = F::Output;
+
+        extern "rust-call" fn call_once(self, args: A) -> F::Output {
+            (*self).call(args)
+        }
+    }
 
-    extern "rust-call" fn call_once(mut self, args: A) -> <F as FnMut<A>>::Output {
-        self.call_mut(args)
+    impl<'a,A,F:?Sized> FnMut<A> for &'a mut F
+        where F : FnMut<A>
+    {
+        extern "rust-call" fn call_mut(&mut self, args: A) -> F::Output {
+            (*self).call_mut(args)
+        }
+    }
+
+    impl<'a,A,F:?Sized> FnOnce<A> for &'a mut F
+        where F : FnMut<A>
+    {
+        type Output = F::Output;
+        extern "rust-call" fn call_once(mut self, args: A) -> F::Output {
+            (*self).call_mut(args)
+        }
     }
 }