From 7d3c5f020e66d01686adf98881b957be9d939021 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 2 Jan 2015 22:56:24 -0500
Subject: [PATCH] use assoc types in unop traits

---
 src/libcore/num/mod.rs                       |  8 ++---
 src/libcore/ops.rs                           | 36 +++++++++++++++-----
 src/libstd/bitflags.rs                       |  4 ++-
 src/libstd/time/duration.rs                  |  4 ++-
 src/test/compile-fail/unop-move-semantics.rs |  6 ++--
 src/test/run-pass/operator-overloading.rs    |  8 +++--
 6 files changed, 46 insertions(+), 20 deletions(-)

diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index c642ff0c2e4..254788f9a75 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -58,7 +58,7 @@ pub trait Int
     + Mul<Output=Self>
     + Div<Output=Self>
     + Rem<Output=Self>
-    + Not<Self>
+    + Not<Output=Self>
     + BitAnd<Output=Self>
     + BitOr<Output=Self>
     + BitXor<Output=Self>
@@ -613,7 +613,7 @@ int_impl! { int = i64, u64, 64,
 #[unstable = "recently settled as part of numerics reform"]
 pub trait SignedInt
     : Int
-    + Neg<Self>
+    + Neg<Output=Self>
 {
     /// Computes the absolute value of `self`. `Int::min_value()` will be
     /// returned if the number is `Int::min_value()`.
@@ -1245,7 +1245,7 @@ pub trait Float
     + NumCast
     + PartialOrd
     + PartialEq
-    + Neg<Self>
+    + Neg<Output=Self>
     + Add<Output=Self>
     + Sub<Output=Self>
     + Mul<Output=Self>
@@ -1718,7 +1718,7 @@ macro_rules! trait_impl {
 #[deprecated = "Generalised numbers are no longer supported"]
 #[allow(deprecated)]
 pub trait Num: PartialEq + Zero + One
-             + Neg<Self>
+             + Neg<Output=Self>
              + Add<Output=Self>
              + Sub<Output=Self>
              + Mul<Output=Self>
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 1bf22d65ffb..642376f1d8e 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -360,13 +360,17 @@ rem_float_impl! { f64, fmod }
 /// `neg`, and therefore, `main` prints `Negating!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::Neg;
 ///
 /// struct Foo;
 ///
 /// impl Copy for Foo {}
 ///
-/// impl Neg<Foo> for Foo {
+/// impl Neg for Foo {
+///     type Output = Foo;
+///
 ///     fn neg(self) -> Foo {
 ///         println!("Negating!");
 ///         self
@@ -378,14 +382,18 @@ rem_float_impl! { f64, fmod }
 /// }
 /// ```
 #[lang="neg"]
-pub trait Neg<Result> {
+pub trait Neg {
+    type Output;
+
     /// The method for the unary `-` operator
-    fn neg(self) -> Result;
+    fn neg(self) -> Self::Output;
 }
 
 macro_rules! neg_impl {
     ($($t:ty)*) => ($(
-        impl Neg<$t> for $t {
+        impl Neg for $t {
+            type Output = $t;
+
             #[inline]
             fn neg(self) -> $t { -self }
         }
@@ -394,7 +402,9 @@ macro_rules! neg_impl {
 
 macro_rules! neg_uint_impl {
     ($t:ty, $t_signed:ty) => {
-        impl Neg<$t> for $t {
+        impl Neg for $t {
+            type Output = $t;
+
             #[inline]
             fn neg(self) -> $t { -(self as $t_signed) as $t }
         }
@@ -418,13 +428,17 @@ neg_uint_impl! { u64, i64 }
 /// `not`, and therefore, `main` prints `Not-ing!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::Not;
 ///
 /// struct Foo;
 ///
 /// impl Copy for Foo {}
 ///
-/// impl Not<Foo> for Foo {
+/// impl Not for Foo {
+///     type Output = Foo;
+///
 ///     fn not(self) -> Foo {
 ///         println!("Not-ing!");
 ///         self
@@ -436,14 +450,18 @@ neg_uint_impl! { u64, i64 }
 /// }
 /// ```
 #[lang="not"]
-pub trait Not<Result> {
+pub trait Not {
+    type Output;
+
     /// The method for the unary `!` operator
-    fn not(self) -> Result;
+    fn not(self) -> Self::Output;
 }
 
 macro_rules! not_impl {
     ($($t:ty)*) => ($(
-        impl Not<$t> for $t {
+        impl Not for $t {
+            type Output = $t;
+
             #[inline]
             fn not(self) -> $t { !self }
         }
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index a9c74823dde..16bc6b16598 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -249,7 +249,9 @@ macro_rules! bitflags {
             }
         }
 
-        impl ::std::ops::Not<$BitFlags> for $BitFlags {
+        impl ::std::ops::Not for $BitFlags {
+            type Output = $BitFlags;
+
             /// Returns the complement of this set of flags.
             #[inline]
             fn not(self) -> $BitFlags {
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 1e148105cc6..41a130492c0 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -262,7 +262,9 @@ impl Duration {
     }
 }
 
-impl Neg<Duration> for Duration {
+impl Neg for Duration {
+    type Output = Duration;
+
     #[inline]
     fn neg(self) -> Duration {
         if self.nanos == 0 {
diff --git a/src/test/compile-fail/unop-move-semantics.rs b/src/test/compile-fail/unop-move-semantics.rs
index c458c539c07..f8cbdb4e160 100644
--- a/src/test/compile-fail/unop-move-semantics.rs
+++ b/src/test/compile-fail/unop-move-semantics.rs
@@ -12,13 +12,13 @@
 
 use std::ops::Not;
 
-fn move_then_borrow<T: Not<T> + Clone>(x: T) {
+fn move_then_borrow<T: Not<Output=T> + Clone>(x: T) {
     !x;
 
     x.clone();  //~ ERROR: use of moved value
 }
 
-fn move_borrowed<T: Not<T>>(x: T, mut y: T) {
+fn move_borrowed<T: Not<Output=T>>(x: T, mut y: T) {
     let m = &x;
     let n = &mut y;
 
@@ -27,7 +27,7 @@ fn move_borrowed<T: Not<T>>(x: T, mut y: T) {
     !y;  //~ ERROR: cannot move out of `y` because it is borrowed
 }
 
-fn illegal_dereference<T: Not<T>>(mut x: T, y: T) {
+fn illegal_dereference<T: Not<Output=T>>(mut x: T, y: T) {
     let m = &mut x;
     let n = &y;
 
diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs
index b23133c53da..58c433e570e 100644
--- a/src/test/run-pass/operator-overloading.rs
+++ b/src/test/run-pass/operator-overloading.rs
@@ -35,13 +35,17 @@ impl ops::Sub for Point {
     }
 }
 
-impl ops::Neg<Point> for Point {
+impl ops::Neg for Point {
+    type Output = Point;
+
     fn neg(self) -> Point {
         Point {x: -self.x, y: -self.y}
     }
 }
 
-impl ops::Not<Point> for Point {
+impl ops::Not for Point {
+    type Output = Point;
+
     fn not(self) -> Point {
         Point {x: !self.x, y: !self.y }
     }