]> 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 16d03901239b3ea417ba47c69c9987c13174933a..faf305c6a13783e6965aaf061d5f46ffb8030790 100644 (file)
@@ -165,7 +165,7 @@ fn $method(self, other: &'a $u) -> <$t as $imp<$u>>::Output {
 /// ```
 /// use std::ops::Add;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Add for Foo {
@@ -219,7 +219,7 @@ fn add(self, other: $t) -> $t { self + other }
 /// ```
 /// use std::ops::Sub;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Sub for Foo {
@@ -273,7 +273,7 @@ fn sub(self, other: $t) -> $t { self - other }
 /// ```
 /// use std::ops::Mul;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl Mul for Foo {
@@ -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 {
@@ -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 {
@@ -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,44 +482,40 @@ 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 `!`.
 ///
@@ -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 {
@@ -585,7 +581,7 @@ fn not(self) -> $t { !self }
 /// ```
 /// use std::ops::BitAnd;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 ///
 /// impl BitAnd for Foo {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -891,7 +887,7 @@ macro_rules! shr_impl_all {
 /// ```
 /// use std::ops::Index;
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
@@ -917,12 +913,6 @@ pub trait Index<Idx: ?Sized> {
     type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
-    #[cfg(stage0)]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
-
-    /// The method for the indexing (`Foo[Bar]`) operation
-    #[cfg(not(stage0))]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
 }
@@ -938,7 +928,7 @@ pub trait Index<Idx: ?Sized> {
 /// ```
 /// use std::ops::{Index, IndexMut};
 ///
-/// #[derive(Copy)]
+/// #[derive(Copy, Clone)]
 /// struct Foo;
 /// struct Bar;
 ///
@@ -966,12 +956,6 @@ pub trait Index<Idx: ?Sized> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
     /// The method for the indexing (`Foo[Bar]`) operation
-    #[cfg(stage0)]
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
-
-    /// The method for the indexing (`Foo[Bar]`) operation
-    #[cfg(not(stage0))]
     #[stable(feature = "rust1", since = "1.0.0")]
     fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
 }
@@ -1149,20 +1133,7 @@ fn deref_mut(&mut self) -> &mut T { *self }
 #[lang="fn"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
-#[cfg(stage0)]
-pub trait Fn<Args> {
-    /// The returned type after the call operator is used.
-    type Output;
-
-    /// This is called when the call operator is used.
-    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
-}
-
-/// A version of the call operator that takes an immutable receiver.
-#[lang="fn"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_paren_sugar]
-#[cfg(not(stage0))]
+#[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;
@@ -1172,20 +1143,7 @@ pub trait Fn<Args> : FnMut<Args> {
 #[lang="fn_mut"]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_paren_sugar]
-#[cfg(stage0)]
-pub trait FnMut<Args> {
-    /// The returned type after the call operator is used.
-    type Output;
-
-    /// This is called when the call operator is used.
-    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
-}
-
-/// A version of the call operator that takes a mutable receiver.
-#[lang="fn_mut"]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_paren_sugar]
-#[cfg(not(stage0))]
+#[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;
@@ -1195,6 +1153,7 @@ pub trait FnMut<Args> : FnOnce<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;
@@ -1203,24 +1162,51 @@ pub trait FnOnce<Args> {
     extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
 }
 
-#[cfg(stage0)]
-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};
+
+    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)
+        }
+    }
 
-    extern "rust-call" fn call_mut(&mut self, args: A) -> <F as Fn<A>>::Output {
-        self.call(args)
+    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)
+        }
     }
-}
 
-#[cfg(stage0)]
-impl<F,A> FnOnce<A> for F
-    where F : FnMut<A>
-{
-    type Output = <F as FnMut<A>>::Output;
+    impl<'a,A,F:?Sized> FnOnce<A> for &'a F
+        where F : Fn<A>
+    {
+        type Output = F::Output;
 
-    extern "rust-call" fn call_once(mut self, args: A) -> <F as FnMut<A>>::Output {
-        self.call_mut(args)
+        extern "rust-call" fn call_once(self, args: A) -> F::Output {
+            (*self).call(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)
+        }
     }
 }