about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcollections/btree/set.rs16
-rw-r--r--src/libcollections/enum_set.rs16
-rw-r--r--src/libcollections/string.rs4
-rw-r--r--src/libcollections/vec.rs4
-rw-r--r--src/libcore/iter.rs2
-rw-r--r--src/libcore/num/mod.rs46
-rw-r--r--src/libcore/ops.rs174
-rw-r--r--src/libcoretest/num/mod.rs6
-rw-r--r--src/librustc/middle/ty.rs12
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/stability_summary.rs4
-rw-r--r--src/libstd/bitflags.rs16
-rw-r--r--src/libstd/collections/hash/set.rs16
-rw-r--r--src/libstd/num/mod.rs6
-rw-r--r--src/libstd/time/duration.rs16
-rw-r--r--src/libsyntax/codemap.rs16
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs4
-rw-r--r--src/libtime/lib.rs10
-rw-r--r--src/test/auxiliary/trait_inheritance_overloading_xc.rs16
-rw-r--r--src/test/auxiliary/unboxed-closures-cross-crate.rs2
-rw-r--r--src/test/compile-fail/binop-consume-args.rs22
-rw-r--r--src/test/compile-fail/binop-move-semantics.rs18
-rw-r--r--src/test/compile-fail/borrowck-loan-in-overloaded-op.rs6
-rw-r--r--src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs6
-rw-r--r--src/test/compile-fail/issue-2149.rs1
-rw-r--r--src/test/compile-fail/wrong-mul-method-signature.rs14
-rw-r--r--src/test/run-pass/deriving-zero.rs16
-rw-r--r--src/test/run-pass/issue-3743.rs6
-rw-r--r--src/test/run-pass/issue-3979-generics.rs2
-rw-r--r--src/test/run-pass/issue-7784.rs2
-rw-r--r--src/test/run-pass/operator-multidispatch.rs10
-rw-r--r--src/test/run-pass/operator-overloading.rs9
-rw-r--r--src/test/run-pass/overloaded-calls-param-vtables.rs4
-rw-r--r--src/test/run-pass/simd-generics.rs8
-rw-r--r--src/test/run-pass/supertrait-default-generics.rs4
-rw-r--r--src/test/run-pass/trait-inheritance-overloading.rs16
36 files changed, 375 insertions, 156 deletions
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 6512243ed1a..a2899f76dad 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -462,7 +462,9 @@ impl<T: Ord> Default for BTreeSet<T> {
 }
 
 #[stable]
-impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
+impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>> for &'a BTreeSet<T> {
+    type Output = BTreeSet<T>;
+
     /// Returns the difference of `self` and `rhs` as a new `BTreeSet<T>`.
     ///
     /// # Examples
@@ -483,7 +485,9 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<
 }
 
 #[stable]
-impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
+impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>> for &'a BTreeSet<T> {
+    type Output = BTreeSet<T>;
+
     /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet<T>`.
     ///
     /// # Examples
@@ -504,7 +508,9 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeS
 }
 
 #[stable]
-impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
+impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>> for &'a BTreeSet<T> {
+    type Output = BTreeSet<T>;
+
     /// Returns the intersection of `self` and `rhs` as a new `BTreeSet<T>`.
     ///
     /// # Examples
@@ -525,7 +531,9 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeS
 }
 
 #[stable]
-impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>, BTreeSet<T>> for &'a BTreeSet<T> {
+impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
+    type Output = BTreeSet<T>;
+
     /// Returns the union of `self` and `rhs` as a new `BTreeSet<T>`.
     ///
     /// # Examples
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index 1d6caf2ccee..81e1541bea0 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -185,25 +185,33 @@ impl<E:CLike> EnumSet<E> {
     }
 }
 
-impl<E:CLike> Sub<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+impl<E:CLike> Sub for EnumSet<E> {
+    type Output = EnumSet<E>;
+
     fn sub(self, e: EnumSet<E>) -> EnumSet<E> {
         EnumSet {bits: self.bits & !e.bits}
     }
 }
 
-impl<E:CLike> BitOr<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+impl<E:CLike> BitOr for EnumSet<E> {
+    type Output = EnumSet<E>;
+
     fn bitor(self, e: EnumSet<E>) -> EnumSet<E> {
         EnumSet {bits: self.bits | e.bits}
     }
 }
 
-impl<E:CLike> BitAnd<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+impl<E:CLike> BitAnd for EnumSet<E> {
+    type Output = EnumSet<E>;
+
     fn bitand(self, e: EnumSet<E>) -> EnumSet<E> {
         EnumSet {bits: self.bits & e.bits}
     }
 }
 
-impl<E:CLike> BitXor<EnumSet<E>, EnumSet<E>> for EnumSet<E> {
+impl<E:CLike> BitXor for EnumSet<E> {
+    type Output = EnumSet<E>;
+
     fn bitxor(self, e: EnumSet<E>) -> EnumSet<E> {
         EnumSet {bits: self.bits ^ e.bits}
     }
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 99273d9575b..35fa3fb55de 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -911,7 +911,9 @@ impl<'a, S: Str> Equiv<S> for String {
 }
 
 #[experimental = "waiting on Add stabilization"]
-impl<'a> Add<&'a str, String> for String {
+impl<'a> Add<&'a str> for String {
+    type Output = String;
+
     fn add(mut self, other: &str) -> String {
         self.push_str(other);
         self
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index cba2824cf9b..39eb37e3dd9 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1451,7 +1451,9 @@ impl<T> AsSlice<T> for Vec<T> {
     }
 }
 
-impl<'a, T: Clone> Add<&'a [T], Vec<T>> for Vec<T> {
+impl<'a, T: Clone> Add<&'a [T]> for Vec<T> {
+    type Output = Vec<T>;
+
     #[inline]
     fn add(mut self, rhs: &[T]) -> Vec<T> {
         self.push_all(rhs);
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 963377ff6b3..f65857b37fb 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2453,7 +2453,7 @@ pub fn count<A>(start: A, step: A) -> Counter<A> {
 }
 
 #[unstable = "trait is unstable"]
-impl<A: Add<A, A> + Clone> Iterator for Counter<A> {
+impl<A: Add<Output=A> + Clone> Iterator for Counter<A> {
     type Item = A;
 
     #[inline]
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index d16478dd6cc..c642ff0c2e4 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -35,7 +35,7 @@ use str::{FromStr, from_str, StrExt};
 /// Simultaneous division and remainder
 #[inline]
 #[deprecated = "use division and remainder directly"]
-pub fn div_rem<T: Clone + Div<T, T> + Rem<T, T>>(x: T, y: T) -> (T, T) {
+pub fn div_rem<T: Clone + Div<Output=T> + Rem<Output=T>>(x: T, y: T) -> (T, T) {
     (x.clone() / y.clone(), x % y)
 }
 
@@ -53,17 +53,17 @@ pub trait Int
     + NumCast
     + PartialOrd + Ord
     + PartialEq + Eq
-    + Add<Self,Self>
-    + Sub<Self,Self>
-    + Mul<Self,Self>
-    + Div<Self,Self>
-    + Rem<Self,Self>
+    + Add<Output=Self>
+    + Sub<Output=Self>
+    + Mul<Output=Self>
+    + Div<Output=Self>
+    + Rem<Output=Self>
     + Not<Self>
-    + BitAnd<Self,Self>
-    + BitOr<Self,Self>
-    + BitXor<Self,Self>
-    + Shl<uint,Self>
-    + Shr<uint,Self>
+    + BitAnd<Output=Self>
+    + BitOr<Output=Self>
+    + BitXor<Output=Self>
+    + Shl<uint, Output=Self>
+    + Shr<uint, Output=Self>
 {
     /// Returns the `0` value of this integer type.
     // FIXME (#5527): Should be an associated constant
@@ -1246,11 +1246,11 @@ pub trait Float
     + PartialOrd
     + PartialEq
     + Neg<Self>
-    + Add<Self,Self>
-    + Sub<Self,Self>
-    + Mul<Self,Self>
-    + Div<Self,Self>
-    + Rem<Self,Self>
+    + Add<Output=Self>
+    + Sub<Output=Self>
+    + Mul<Output=Self>
+    + Div<Output=Self>
+    + Rem<Output=Self>
 {
     /// Returns the NaN value.
     fn nan() -> Self;
@@ -1719,11 +1719,11 @@ macro_rules! trait_impl {
 #[allow(deprecated)]
 pub trait Num: PartialEq + Zero + One
              + Neg<Self>
-             + Add<Self,Self>
-             + Sub<Self,Self>
-             + Mul<Self,Self>
-             + Div<Self,Self>
-             + Rem<Self,Self> {}
+             + Add<Output=Self>
+             + Sub<Output=Self>
+             + Mul<Output=Self>
+             + Div<Output=Self>
+             + Rem<Output=Self> {}
 trait_impl! { Num for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 
 #[deprecated = "Generalised unsigned numbers are no longer supported"]
@@ -1737,7 +1737,7 @@ pub trait Primitive: Copy + Clone + Num + NumCast + PartialOrd {}
 trait_impl! { Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 
 #[deprecated = "The generic `Zero` trait will be removed soon."]
-pub trait Zero: Add<Self, Self> {
+pub trait Zero: Add<Output=Self> {
     #[deprecated = "Use `Int::zero()` or `Float::zero()`."]
     fn zero() -> Self;
     #[deprecated = "Use `x == Int::zero()` or `x == Float::zero()`."]
@@ -1768,7 +1768,7 @@ zero_impl! { f32, 0.0f32 }
 zero_impl! { f64, 0.0f64 }
 
 #[deprecated = "The generic `One` trait will be removed soon."]
-pub trait One: Mul<Self, Self> {
+pub trait One: Mul<Output=Self> {
     #[deprecated = "Use `Int::one()` or `Float::one()`."]
     fn one() -> Self;
 }
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index c5441359ad0..1bf22d65ffb 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -25,6 +25,8 @@
 //! demonstrates adding and subtracting two `Point`s.
 //!
 //! ```rust
+//! #![feature(associated_types)]
+//!
 //! use std::ops::{Add, Sub};
 //!
 //! #[deriving(Show)]
@@ -33,13 +35,17 @@
 //!     y: int
 //! }
 //!
-//! impl Add<Point, Point> for Point {
+//! 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<Point, Point> for Point {
+//! impl Sub for Point {
+//!     type Output = Point;
+//!
 //!     fn sub(self, other: Point) -> Point {
 //!         Point {x: self.x - other.x, y: self.y - other.y}
 //!     }
@@ -93,12 +99,16 @@ pub trait Drop {
 /// calling `add`, and therefore, `main` prints `Adding!`.
 ///
 /// ```rust
+/// #![feature(associated_types)]
+///
 /// use std::ops::Add;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Add<Foo, Foo> for Foo {
+/// impl Add for Foo {
+///     type Output = Foo;
+///
 ///     fn add(self, _rhs: Foo) -> Foo {
 ///       println!("Adding!");
 ///       self
@@ -110,14 +120,18 @@ pub trait Drop {
 /// }
 /// ```
 #[lang="add"]
-pub trait Add<RHS, Result> {
+pub trait Add<RHS=Self> {
+    type Output;
+
     /// The method for the `+` operator
-    fn add(self, rhs: RHS) -> Result;
+    fn add(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! add_impl {
     ($($t:ty)*) => ($(
-        impl Add<$t, $t> for $t {
+        impl Add for $t {
+            type Output = $t;
+
             #[inline]
             fn add(self, other: $t) -> $t { self + other }
         }
@@ -134,12 +148,16 @@ add_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `sub`, and therefore, `main` prints `Subtracting!`.
 ///
 /// ```rust
+/// #![feature(associated_types)]
+///
 /// use std::ops::Sub;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Sub<Foo, Foo> for Foo {
+/// impl Sub for Foo {
+///     type Output = Foo;
+///
 ///     fn sub(self, _rhs: Foo) -> Foo {
 ///         println!("Subtracting!");
 ///         self
@@ -151,14 +169,18 @@ add_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// }
 /// ```
 #[lang="sub"]
-pub trait Sub<RHS, Result> {
+pub trait Sub<RHS=Self> {
+    type Output;
+
     /// The method for the `-` operator
-    fn sub(self, rhs: RHS) -> Result;
+    fn sub(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! sub_impl {
     ($($t:ty)*) => ($(
-        impl Sub<$t, $t> for $t {
+        impl Sub for $t {
+            type Output = $t;
+
             #[inline]
             fn sub(self, other: $t) -> $t { self - other }
         }
@@ -175,12 +197,16 @@ sub_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `mul`, and therefore, `main` prints `Multiplying!`.
 ///
 /// ```rust
+/// #![feature(associated_types)]
+///
 /// use std::ops::Mul;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Mul<Foo, Foo> for Foo {
+/// impl Mul for Foo {
+///     type Output = Foo;
+///
 ///     fn mul(self, _rhs: Foo) -> Foo {
 ///         println!("Multiplying!");
 ///         self
@@ -192,14 +218,18 @@ sub_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// }
 /// ```
 #[lang="mul"]
-pub trait Mul<RHS, Result> {
+pub trait Mul<RHS=Self> {
+    type Output;
+
     /// The method for the `*` operator
-    fn mul(self, rhs: RHS) -> Result;
+    fn mul(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! mul_impl {
     ($($t:ty)*) => ($(
-        impl Mul<$t, $t> for $t {
+        impl Mul for $t {
+            type Output = $t;
+
             #[inline]
             fn mul(self, other: $t) -> $t { self * other }
         }
@@ -216,12 +246,16 @@ mul_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `div`, and therefore, `main` prints `Dividing!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::Div;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Div<Foo, Foo> for Foo {
+/// impl Div for Foo {
+///     type Output = Foo;
+///
 ///     fn div(self, _rhs: Foo) -> Foo {
 ///         println!("Dividing!");
 ///         self
@@ -233,14 +267,18 @@ mul_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// }
 /// ```
 #[lang="div"]
-pub trait Div<RHS, Result> {
+pub trait Div<RHS=Self> {
+    type Output;
+
     /// The method for the `/` operator
-    fn div(self, rhs: RHS) -> Result;
+    fn div(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! div_impl {
     ($($t:ty)*) => ($(
-        impl Div<$t, $t> for $t {
+        impl Div for $t {
+            type Output = $t;
+
             #[inline]
             fn div(self, other: $t) -> $t { self / other }
         }
@@ -257,12 +295,16 @@ div_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// calling `rem`, and therefore, `main` prints `Remainder-ing!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::Rem;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Rem<Foo, Foo> for Foo {
+/// impl Rem for Foo {
+///     type Output = Foo;
+///
 ///     fn rem(self, _rhs: Foo) -> Foo {
 ///         println!("Remainder-ing!");
 ///         self
@@ -274,14 +316,18 @@ div_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64 }
 /// }
 /// ```
 #[lang="rem"]
-pub trait Rem<RHS, Result> {
+pub trait Rem<RHS=Self> {
+    type Output = Self;
+
     /// The method for the `%` operator
-    fn rem(self, rhs: RHS) -> Result;
+    fn rem(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! rem_impl {
     ($($t:ty)*) => ($(
-        impl Rem<$t, $t> for $t {
+        impl Rem for $t {
+            type Output = $t;
+
             #[inline]
             fn rem(self, other: $t) -> $t { self % other }
         }
@@ -290,7 +336,9 @@ macro_rules! rem_impl {
 
 macro_rules! rem_float_impl {
     ($t:ty, $fmod:ident) => {
-        impl Rem<$t, $t> for $t {
+        impl Rem for $t {
+            type Output = $t;
+
             #[inline]
             fn rem(self, other: $t) -> $t {
                 extern { fn $fmod(a: $t, b: $t) -> $t; }
@@ -412,12 +460,16 @@ not_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `bitand`, and therefore, `main` prints `Bitwise And-ing!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::BitAnd;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl BitAnd<Foo, Foo> for Foo {
+/// impl BitAnd for Foo {
+///     type Output = Foo;
+///
 ///     fn bitand(self, _rhs: Foo) -> Foo {
 ///         println!("Bitwise And-ing!");
 ///         self
@@ -429,14 +481,18 @@ not_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// }
 /// ```
 #[lang="bitand"]
-pub trait BitAnd<RHS, Result> {
+pub trait BitAnd<RHS=Self> {
+    type Output;
+
     /// The method for the `&` operator
-    fn bitand(self, rhs: RHS) -> Result;
+    fn bitand(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! bitand_impl {
     ($($t:ty)*) => ($(
-        impl BitAnd<$t, $t> for $t {
+        impl BitAnd for $t {
+            type Output = $t;
+
             #[inline]
             fn bitand(self, rhs: $t) -> $t { self & rhs }
         }
@@ -453,12 +509,16 @@ bitand_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `bitor`, and therefore, `main` prints `Bitwise Or-ing!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::BitOr;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl BitOr<Foo, Foo> for Foo {
+/// impl BitOr for Foo {
+///     type Output = Foo;
+///
 ///     fn bitor(self, _rhs: Foo) -> Foo {
 ///         println!("Bitwise Or-ing!");
 ///         self
@@ -470,14 +530,18 @@ bitand_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// }
 /// ```
 #[lang="bitor"]
-pub trait BitOr<RHS, Result> {
+pub trait BitOr<RHS=Self> {
+    type Output;
+
     /// The method for the `|` operator
-    fn bitor(self, rhs: RHS) -> Result;
+    fn bitor(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! bitor_impl {
     ($($t:ty)*) => ($(
-        impl BitOr<$t,$t> for $t {
+        impl BitOr for $t {
+            type Output = $t;
+
             #[inline]
             fn bitor(self, rhs: $t) -> $t { self | rhs }
         }
@@ -494,12 +558,16 @@ bitor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `bitxor`, and therefore, `main` prints `Bitwise Xor-ing!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::BitXor;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl BitXor<Foo, Foo> for Foo {
+/// impl BitXor for Foo {
+///     type Output = Foo;
+///
 ///     fn bitxor(self, _rhs: Foo) -> Foo {
 ///         println!("Bitwise Xor-ing!");
 ///         self
@@ -511,14 +579,18 @@ bitor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// }
 /// ```
 #[lang="bitxor"]
-pub trait BitXor<RHS, Result> {
+pub trait BitXor<RHS=Self> {
+    type Output;
+
     /// The method for the `^` operator
-    fn bitxor(self, rhs: RHS) -> Result;
+    fn bitxor(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! bitxor_impl {
     ($($t:ty)*) => ($(
-        impl BitXor<$t, $t> for $t {
+        impl BitXor for $t {
+            type Output = $t;
+
             #[inline]
             fn bitxor(self, other: $t) -> $t { self ^ other }
         }
@@ -535,12 +607,16 @@ bitxor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `shl`, and therefore, `main` prints `Shifting left!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::Shl;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Shl<Foo, Foo> for Foo {
+/// impl Shl<Foo> for Foo {
+///     type Output = Foo;
+///
 ///     fn shl(self, _rhs: Foo) -> Foo {
 ///         println!("Shifting left!");
 ///         self
@@ -552,14 +628,18 @@ bitxor_impl! { bool uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// }
 /// ```
 #[lang="shl"]
-pub trait Shl<RHS, Result> {
+pub trait Shl<RHS> {
+    type Output;
+
     /// The method for the `<<` operator
-    fn shl(self, rhs: RHS) -> Result;
+    fn shl(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! shl_impl {
     ($($t:ty)*) => ($(
-        impl Shl<uint, $t> for $t {
+        impl Shl<uint> for $t {
+            type Output = $t;
+
             #[inline]
             fn shl(self, other: uint) -> $t {
                 self << other
@@ -578,12 +658,16 @@ shl_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// calling `shr`, and therefore, `main` prints `Shifting right!`.
 ///
 /// ```
+/// #![feature(associated_types)]
+///
 /// use std::ops::Shr;
 ///
 /// #[deriving(Copy)]
 /// struct Foo;
 ///
-/// impl Shr<Foo, Foo> for Foo {
+/// impl Shr<Foo> for Foo {
+///     type Output = Foo;
+///
 ///     fn shr(self, _rhs: Foo) -> Foo {
 ///         println!("Shifting right!");
 ///         self
@@ -595,14 +679,18 @@ shl_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
 /// }
 /// ```
 #[lang="shr"]
-pub trait Shr<RHS, Result> {
+pub trait Shr<RHS> {
+    type Output;
+
     /// The method for the `>>` operator
-    fn shr(self, rhs: RHS) -> Result;
+    fn shr(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! shr_impl {
     ($($t:ty)*) => ($(
-        impl Shr<uint, $t> for $t {
+        impl Shr<uint> for $t {
+            type Output = $t;
+
             #[inline]
             fn shr(self, other: uint) -> $t { self >> other }
         }
diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs
index 82e91c5b712..274b4cee3ba 100644
--- a/src/libcoretest/num/mod.rs
+++ b/src/libcoretest/num/mod.rs
@@ -31,9 +31,9 @@ mod uint;
 /// Helper function for testing numeric operations
 pub fn test_num<T>(ten: T, two: T) where
     T: PartialEq + NumCast
-     + Add<T, T> + Sub<T, T>
-     + Mul<T, T> + Div<T, T>
-     + Rem<T, T> + Show
+     + Add<Output=T> + Sub<Output=T>
+     + Mul<Output=T> + Div<Output=T>
+     + Rem<Output=T> + Show
      + Copy
 {
     assert_eq!(ten.add(two),  cast(12i).unwrap());
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index f786ef8afee..884255f2127 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -3240,19 +3240,25 @@ impl TypeContents {
     }
 }
 
-impl ops::BitOr<TypeContents,TypeContents> for TypeContents {
+impl ops::BitOr for TypeContents {
+    type Output = TypeContents;
+
     fn bitor(self, other: TypeContents) -> TypeContents {
         TypeContents {bits: self.bits | other.bits}
     }
 }
 
-impl ops::BitAnd<TypeContents, TypeContents> for TypeContents {
+impl ops::BitAnd for TypeContents {
+    type Output = TypeContents;
+
     fn bitand(self, other: TypeContents) -> TypeContents {
         TypeContents {bits: self.bits & other.bits}
     }
 }
 
-impl ops::Sub<TypeContents, TypeContents> for TypeContents {
+impl ops::Sub for TypeContents {
+    type Output = TypeContents;
+
     fn sub(self, other: TypeContents) -> TypeContents {
         TypeContents {bits: self.bits & !other.bits}
     }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1beeeaf629d..f0feb8de1ce 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -21,6 +21,7 @@
 #![feature(globs, macro_rules, phase, slicing_syntax)]
 #![feature(unboxed_closures)]
 #![feature(old_orphan_check)]
+#![feature(associated_types)]
 
 extern crate arena;
 extern crate getopts;
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 058a7acd455..0d6d7a47c85 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -41,7 +41,9 @@ pub struct Counts {
     pub unmarked: uint,
 }
 
-impl Add<Counts, Counts> for Counts {
+impl Add for Counts {
+    type Output = Counts;
+
     fn add(self, other: Counts) -> Counts {
         Counts {
             deprecated:   self.deprecated   + other.deprecated,
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index c07531d3f32..a9c74823dde 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -209,7 +209,9 @@ macro_rules! bitflags {
             }
         }
 
-        impl ::std::ops::BitOr<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::BitOr for $BitFlags {
+            type Output = $BitFlags;
+
             /// Returns the union of the two sets of flags.
             #[inline]
             fn bitor(self, other: $BitFlags) -> $BitFlags {
@@ -217,7 +219,9 @@ macro_rules! bitflags {
             }
         }
 
-        impl ::std::ops::BitXor<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::BitXor for $BitFlags {
+            type Output = $BitFlags;
+
             /// Returns the left flags, but with all the right flags toggled.
             #[inline]
             fn bitxor(self, other: $BitFlags) -> $BitFlags {
@@ -225,7 +229,9 @@ macro_rules! bitflags {
             }
         }
 
-        impl ::std::ops::BitAnd<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::BitAnd for $BitFlags {
+            type Output = $BitFlags;
+
             /// Returns the intersection between the two sets of flags.
             #[inline]
             fn bitand(self, other: $BitFlags) -> $BitFlags {
@@ -233,7 +239,9 @@ macro_rules! bitflags {
             }
         }
 
-        impl ::std::ops::Sub<$BitFlags, $BitFlags> for $BitFlags {
+        impl ::std::ops::Sub for $BitFlags {
+            type Output = $BitFlags;
+
             /// Returns the set difference of the two sets of flags.
             #[inline]
             fn sub(self, other: $BitFlags) -> $BitFlags {
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index ea8298c48c8..4c6a74a78d5 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -630,7 +630,9 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
 
 #[stable]
 impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
-BitOr<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+BitOr<&'b HashSet<T, H>> for &'a HashSet<T, H> {
+    type Output = HashSet<T, H>;
+
     /// Returns the union of `self` and `rhs` as a new `HashSet<T, H>`.
     ///
     /// # Examples
@@ -658,7 +660,9 @@ BitOr<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
 
 #[stable]
 impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
-BitAnd<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+BitAnd<&'b HashSet<T, H>> for &'a HashSet<T, H> {
+    type Output = HashSet<T, H>;
+
     /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, H>`.
     ///
     /// # Examples
@@ -686,7 +690,9 @@ BitAnd<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
 
 #[stable]
 impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
-BitXor<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+BitXor<&'b HashSet<T, H>> for &'a HashSet<T, H> {
+    type Output = HashSet<T, H>;
+
     /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, H>`.
     ///
     /// # Examples
@@ -714,7 +720,9 @@ BitXor<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
 
 #[stable]
 impl<'a, 'b, T: Eq + Hash<S> + Clone, S, H: Hasher<S> + Default>
-Sub<&'b HashSet<T, H>, HashSet<T, H>> for &'a HashSet<T, H> {
+Sub<&'b HashSet<T, H>> for &'a HashSet<T, H> {
+    type Output = HashSet<T, H>;
+
     /// Returns the difference of `self` and `rhs` as a new `HashSet<T, H>`.
     ///
     /// # Examples
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 01aa21c692b..007d89a942d 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -127,9 +127,9 @@ pub fn abs_sub<T: FloatMath>(x: T, y: T) -> T {
 #[cfg(test)]
 pub fn test_num<T>(ten: T, two: T) where
     T: PartialEq + NumCast
-     + Add<T, T> + Sub<T, T>
-     + Mul<T, T> + Div<T, T>
-     + Rem<T, T> + Show
+     + Add<Output=T> + Sub<Output=T>
+     + Mul<Output=T> + Div<Output=T>
+     + Rem<Output=T> + Show
      + Copy
 {
     assert_eq!(ten.add(two),  cast(12i).unwrap());
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 51564b53976..1e148105cc6 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -273,7 +273,9 @@ impl Neg<Duration> for Duration {
     }
 }
 
-impl Add<Duration, Duration> for Duration {
+impl Add for Duration {
+    type Output = Duration;
+
     fn add(self, rhs: Duration) -> Duration {
         let mut secs = self.secs + rhs.secs;
         let mut nanos = self.nanos + rhs.nanos;
@@ -285,7 +287,9 @@ impl Add<Duration, Duration> for Duration {
     }
 }
 
-impl Sub<Duration, Duration> for Duration {
+impl Sub for Duration {
+    type Output = Duration;
+
     fn sub(self, rhs: Duration) -> Duration {
         let mut secs = self.secs - rhs.secs;
         let mut nanos = self.nanos - rhs.nanos;
@@ -297,7 +301,9 @@ impl Sub<Duration, Duration> for Duration {
     }
 }
 
-impl Mul<i32, Duration> for Duration {
+impl Mul<i32> for Duration {
+    type Output = Duration;
+
     fn mul(self, rhs: i32) -> Duration {
         // Multiply nanoseconds as i64, because it cannot overflow that way.
         let total_nanos = self.nanos as i64 * rhs as i64;
@@ -307,7 +313,9 @@ impl Mul<i32, Duration> for Duration {
     }
 }
 
-impl Div<i32, Duration> for Duration {
+impl Div<i32> for Duration {
+    type Output = Duration;
+
     fn div(self, rhs: i32) -> Duration {
         let mut secs = self.secs / rhs as i64;
         let carry = self.secs - secs * rhs as i64;
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 5eac6546c6b..eb011faa55d 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -53,13 +53,17 @@ impl Pos for BytePos {
     fn to_uint(&self) -> uint { let BytePos(n) = *self; n as uint }
 }
 
-impl Add<BytePos, BytePos> for BytePos {
+impl Add for BytePos {
+    type Output = BytePos;
+
     fn add(self, rhs: BytePos) -> BytePos {
         BytePos((self.to_uint() + rhs.to_uint()) as u32)
     }
 }
 
-impl Sub<BytePos, BytePos> for BytePos {
+impl Sub for BytePos {
+    type Output = BytePos;
+
     fn sub(self, rhs: BytePos) -> BytePos {
         BytePos((self.to_uint() - rhs.to_uint()) as u32)
     }
@@ -70,13 +74,17 @@ impl Pos for CharPos {
     fn to_uint(&self) -> uint { let CharPos(n) = *self; n }
 }
 
-impl Add<CharPos, CharPos> for CharPos {
+impl Add for CharPos {
+    type Output = CharPos;
+
     fn add(self, rhs: CharPos) -> CharPos {
         CharPos(self.to_uint() + rhs.to_uint())
     }
 }
 
-impl Sub<CharPos, CharPos> for CharPos {
+impl Sub for CharPos {
+    type Output = CharPos;
+
     fn sub(self, rhs: CharPos) -> CharPos {
         CharPos(self.to_uint() - rhs.to_uint())
     }
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index deed0b78e87..8af5e952e9a 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -106,7 +106,9 @@ enum LockstepIterSize {
     LisContradiction(String),
 }
 
-impl Add<LockstepIterSize, LockstepIterSize> for LockstepIterSize {
+impl Add for LockstepIterSize {
+    type Output = LockstepIterSize;
+
     fn add(self, other: LockstepIterSize) -> LockstepIterSize {
         match self {
             LisUnconstrained => other,
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index b2aca684314..7603d84848c 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -24,6 +24,8 @@
 #![allow(unknown_features)]
 #![feature(phase, globs)]
 #![feature(old_orphan_check)]
+#![feature(associated_types)]
+#![feature(default_type_params)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
@@ -100,7 +102,9 @@ impl Timespec {
     }
 }
 
-impl Add<Duration, Timespec> for Timespec {
+impl Add<Duration> for Timespec {
+    type Output = Timespec;
+
     fn add(self, other: Duration) -> Timespec {
         let d_sec = other.num_seconds();
         // It is safe to unwrap the nanoseconds, because there cannot be
@@ -120,7 +124,9 @@ impl Add<Duration, Timespec> for Timespec {
     }
 }
 
-impl Sub<Timespec, Duration> for Timespec {
+impl Sub for Timespec {
+    type Output = Duration;
+
     fn sub(self, other: Timespec) -> Duration {
         let sec = self.sec - other.sec;
         let nsec = self.nsec - other.nsec;
diff --git a/src/test/auxiliary/trait_inheritance_overloading_xc.rs b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
index 7ddf2c43489..7394373e922 100644
--- a/src/test/auxiliary/trait_inheritance_overloading_xc.rs
+++ b/src/test/auxiliary/trait_inheritance_overloading_xc.rs
@@ -8,10 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::cmp::PartialEq;
 use std::ops::{Add, Sub, Mul};
 
-pub trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq + Clone {
+pub trait MyNum : Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + PartialEq + Clone {
 }
 
 #[derive(Clone, Show)]
@@ -19,15 +21,21 @@ pub struct MyInt {
     pub val: int
 }
 
-impl Add<MyInt, MyInt> for MyInt {
+impl Add for MyInt {
+    type Output = MyInt;
+
     fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) }
 }
 
-impl Sub<MyInt, MyInt> for MyInt {
+impl Sub for MyInt {
+    type Output = MyInt;
+
     fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) }
 }
 
-impl Mul<MyInt, MyInt> for MyInt {
+impl Mul for MyInt {
+    type Output = MyInt;
+
     fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) }
 }
 
diff --git a/src/test/auxiliary/unboxed-closures-cross-crate.rs b/src/test/auxiliary/unboxed-closures-cross-crate.rs
index 0b65fa913cb..4bc45caa170 100644
--- a/src/test/auxiliary/unboxed-closures-cross-crate.rs
+++ b/src/test/auxiliary/unboxed-closures-cross-crate.rs
@@ -21,7 +21,7 @@ pub fn has_closures() -> uint {
     f() + g()
 }
 
-pub fn has_generic_closures<T: Add<T,T> + Copy>(x: T, y: T) -> T {
+pub fn has_generic_closures<T: Add<Output=T> + Copy>(x: T, y: T) -> T {
     let mut f = move |&mut:| x;
     let g = |:| y;
     f() + g()
diff --git a/src/test/compile-fail/binop-consume-args.rs b/src/test/compile-fail/binop-consume-args.rs
index afa255be699..930000e5f0c 100644
--- a/src/test/compile-fail/binop-consume-args.rs
+++ b/src/test/compile-fail/binop-consume-args.rs
@@ -10,63 +10,65 @@
 
 // Test that binary operators consume their arguments
 
+#![feature(associated_types, default_type_params)]
+
 use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitXor, BitOr, Shl, Shr};
 
-fn add<A: Add<B, ()>, B>(lhs: A, rhs: B) {
+fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs + rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn sub<A: Sub<B, ()>, B>(lhs: A, rhs: B) {
+fn sub<A: Sub<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs - rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn mul<A: Mul<B, ()>, B>(lhs: A, rhs: B) {
+fn mul<A: Mul<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs * rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn div<A: Div<B, ()>, B>(lhs: A, rhs: B) {
+fn div<A: Div<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs / rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn rem<A: Rem<B, ()>, B>(lhs: A, rhs: B) {
+fn rem<A: Rem<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs % rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn bitand<A: BitAnd<B, ()>, B>(lhs: A, rhs: B) {
+fn bitand<A: BitAnd<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs & rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn bitor<A: BitOr<B, ()>, B>(lhs: A, rhs: B) {
+fn bitor<A: BitOr<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs | rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn bitxor<A: BitXor<B, ()>, B>(lhs: A, rhs: B) {
+fn bitxor<A: BitXor<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs ^ rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn shl<A: Shl<B, ()>, B>(lhs: A, rhs: B) {
+fn shl<A: Shl<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs << rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
 }
 
-fn shr<A: Shr<B, ()>, B>(lhs: A, rhs: B) {
+fn shr<A: Shr<B, Output=()>, B>(lhs: A, rhs: B) {
     lhs >> rhs;
     drop(lhs);  //~ ERROR use of moved value: `lhs`
     drop(rhs);  //~ ERROR use of moved value: `rhs`
diff --git a/src/test/compile-fail/binop-move-semantics.rs b/src/test/compile-fail/binop-move-semantics.rs
index e48c88a49f0..e51ca6a70f2 100644
--- a/src/test/compile-fail/binop-move-semantics.rs
+++ b/src/test/compile-fail/binop-move-semantics.rs
@@ -10,21 +10,23 @@
 
 // Test that move restrictions are enforced on overloaded binary operations
 
+#![feature(associated_types, default_type_params)]
+
 use std::ops::Add;
 
-fn double_move<T: Add<T, ()>>(x: T) {
+fn double_move<T: Add<Output=()>>(x: T) {
     x
     +
     x;  //~ ERROR: use of moved value
 }
 
-fn move_then_borrow<T: Add<T, ()> + Clone>(x: T) {
+fn move_then_borrow<T: Add<Output=()> + Clone>(x: T) {
     x
     +
     x.clone();  //~ ERROR: use of moved value
 }
 
-fn move_borrowed<T: Add<T, ()>>(x: T, mut y: T) {
+fn move_borrowed<T: Add<Output=()>>(x: T, mut y: T) {
     let m = &x;
     let n = &mut y;
 
@@ -33,7 +35,7 @@ fn move_borrowed<T: Add<T, ()>>(x: T, mut y: T) {
     y;  //~ ERROR: cannot move out of `y` because it is borrowed
 }
 
-fn illegal_dereference<T: Add<T, ()>>(mut x: T, y: T) {
+fn illegal_dereference<T: Add<Output=()>>(mut x: T, y: T) {
     let m = &mut x;
     let n = &y;
 
@@ -44,11 +46,15 @@ fn illegal_dereference<T: Add<T, ()>>(mut x: T, y: T) {
 
 struct Foo;
 
-impl<'a, 'b> Add<&'b Foo, ()> for &'a mut Foo {
+impl<'a, 'b> Add<&'b Foo> for &'a mut Foo {
+    type Output = ();
+
     fn add(self, _: &Foo) {}
 }
 
-impl<'a, 'b> Add<&'b mut Foo, ()> for &'a Foo {
+impl<'a, 'b> Add<&'b mut Foo> for &'a Foo {
+    type Output = ();
+
     fn add(self, _: &mut Foo) {}
 }
 
diff --git a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
index bcbb1f08b89..141dd8905be 100644
--- a/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
@@ -8,12 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::ops::Add;
 
 #[derive(Clone)]
 struct foo(Box<uint>);
 
-impl Add<foo, foo> for foo {
+impl Add for foo {
+    type Output = foo;
+
     fn add(self, f: foo) -> foo {
         let foo(box i) = self;
         let foo(box j) = f;
diff --git a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
index a0edd078184..e0a961e5cc5 100644
--- a/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
+++ b/src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types, default_type_params)]
+
 use std::ops::Add;
 
 #[derive(Copy)]
@@ -16,7 +18,9 @@ struct Point {
     y: int,
 }
 
-impl Add<int, int> for Point {
+impl Add<int> for Point {
+    type Output = int;
+
     fn add(self, z: int) -> int {
         self.x + self.y + z
     }
diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs
index 3343e92252f..b688cafb674 100644
--- a/src/test/compile-fail/issue-2149.rs
+++ b/src/test/compile-fail/issue-2149.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 trait vec_monad<A> {
     fn bind<B>(&self, f: |A| -> Vec<B> );
 }
diff --git a/src/test/compile-fail/wrong-mul-method-signature.rs b/src/test/compile-fail/wrong-mul-method-signature.rs
index bde5b853078..7aa6ead89d7 100644
--- a/src/test/compile-fail/wrong-mul-method-signature.rs
+++ b/src/test/compile-fail/wrong-mul-method-signature.rs
@@ -13,6 +13,8 @@
 // (In this case the mul method should take &f64 and not f64)
 // See: #11450
 
+#![feature(associated_types, default_type_params)]
+
 use std::ops::Mul;
 
 struct Vec1 {
@@ -20,7 +22,9 @@ struct Vec1 {
 }
 
 // Expecting value in input signature
-impl Mul<f64, Vec1> for Vec1 {
+impl Mul<f64> for Vec1 {
+    type Output = Vec1;
+
     fn mul(self, s: &f64) -> Vec1 {
     //~^ ERROR: method `mul` has an incompatible type for trait: expected f64, found &-ptr
         Vec1 {
@@ -35,7 +39,9 @@ struct Vec2 {
 }
 
 // Wrong type parameter ordering
-impl Mul<Vec2, f64> for Vec2 {
+impl Mul<Vec2> for Vec2 {
+    type Output = f64;
+
     fn mul(self, s: f64) -> Vec2 {
     //~^ ERROR: method `mul` has an incompatible type for trait: expected struct Vec2, found f64
         Vec2 {
@@ -52,7 +58,9 @@ struct Vec3 {
 }
 
 // Unexpected return type
-impl Mul<f64, i32> for Vec3 {
+impl Mul<f64> for Vec3 {
+    type Output = i32;
+
     fn mul(self, s: f64) -> f64 {
     //~^ ERROR: method `mul` has an incompatible type for trait: expected i32, found f64
         s
diff --git a/src/test/run-pass/deriving-zero.rs b/src/test/run-pass/deriving-zero.rs
index a6c0a592c77..442c330b277 100644
--- a/src/test/run-pass/deriving-zero.rs
+++ b/src/test/run-pass/deriving-zero.rs
@@ -8,13 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::ops::Add;
+#![feature(associated_types)]
+
 use std::num::Zero;
+use std::ops::Add;
 
 #[derive(Zero)]
 struct Vector2<T>(T, T);
 
-impl<T: Add<T, T>> Add<Vector2<T>, Vector2<T>> for Vector2<T> {
+impl<T: Add<Output=T>> Add for Vector2<T> {
+    type Output = Vector2<T>;
+
     fn add(self, other: Vector2<T>) -> Vector2<T> {
         match (self, other) {
             (Vector2(x0, y0), Vector2(x1, y1)) => {
@@ -29,7 +33,9 @@ struct Vector3<T> {
     x: T, y: T, z: T,
 }
 
-impl<T: Add<T, T>> Add<Vector3<T>, Vector3<T>> for Vector3<T> {
+impl<T: Add<Output=T>> Add for Vector3<T> {
+    type Output = Vector3<T>;
+
     fn add(self, other: Vector3<T>) -> Vector3<T> {
         Vector3 {
             x: self.x + other.x,
@@ -46,7 +52,9 @@ struct Matrix3x2<T> {
     z: Vector2<T>,
 }
 
-impl<T: Add<T, T>> Add<Matrix3x2<T>, Matrix3x2<T>> for Matrix3x2<T> {
+impl<T: Add<Output=T>> Add for Matrix3x2<T> {
+    type Output = Matrix3x2<T>;
+
     fn add(self, other: Matrix3x2<T>) -> Matrix3x2<T> {
         Matrix3x2 {
             x: self.x + other.x,
diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs
index cb4f1b7d20f..741f168482d 100644
--- a/src/test/run-pass/issue-3743.rs
+++ b/src/test/run-pass/issue-3743.rs
@@ -10,7 +10,7 @@
 
 // If `Mul` used an associated type for its output, this test would
 // work more smoothly.
-#![feature(old_orphan_check)]
+#![feature(associated_types, default_type_params, old_orphan_check)]
 
 use std::ops::Mul;
 
@@ -33,7 +33,9 @@ impl Vec2 {
 trait RhsOfVec2Mul<Result> { fn mul_vec2_by(&self, lhs: &Vec2) -> Result; }
 
 // Vec2's implementation of Mul "from the other side" using the above trait
-impl<Res, Rhs: RhsOfVec2Mul<Res>> Mul<Rhs,Res> for Vec2 {
+impl<Res, Rhs: RhsOfVec2Mul<Res>> Mul<Rhs> for Vec2 {
+    type Output = Res;
+
     fn mul(self, rhs: Rhs) -> Res { rhs.mul_vec2_by(&self) }
 }
 
diff --git a/src/test/run-pass/issue-3979-generics.rs b/src/test/run-pass/issue-3979-generics.rs
index 93c72e2e350..180bd292f84 100644
--- a/src/test/run-pass/issue-3979-generics.rs
+++ b/src/test/run-pass/issue-3979-generics.rs
@@ -15,7 +15,7 @@ trait Positioned<S> {
   fn X(&self) -> S;
 }
 
-trait Movable<S: Add<S, S>>: Positioned<S> {
+trait Movable<S: Add<Output=S>>: Positioned<S> {
   fn translate(&mut self, dx: S) {
     let x = self.X() + dx;
     self.SetX(x);
diff --git a/src/test/run-pass/issue-7784.rs b/src/test/run-pass/issue-7784.rs
index 43785edc2eb..882ca00f1df 100644
--- a/src/test/run-pass/issue-7784.rs
+++ b/src/test/run-pass/issue-7784.rs
@@ -12,7 +12,7 @@
 
 use std::ops::Add;
 
-fn foo<T: Add<T, T> + Clone>([x, y, z]: [T; 3]) -> (T, T, T) {
+fn foo<T: Add<Output=T> + Clone>([x, y, z]: [T; 3]) -> (T, T, T) {
     (x.clone(), x.clone() + y.clone(), x + y + z)
 }
 fn bar(a: &'static str, b: &'static str) -> [&'static str; 4] {
diff --git a/src/test/run-pass/operator-multidispatch.rs b/src/test/run-pass/operator-multidispatch.rs
index 2394822d9ba..59998400919 100644
--- a/src/test/run-pass/operator-multidispatch.rs
+++ b/src/test/run-pass/operator-multidispatch.rs
@@ -11,6 +11,8 @@
 // Test that we can overload the `+` operator for points so that two
 // points can be added, and a point can be added to an integer.
 
+#![feature(associated_types, default_type_params)]
+
 use std::ops;
 
 #[derive(Show,PartialEq,Eq)]
@@ -19,13 +21,17 @@ struct Point {
     y: int
 }
 
-impl ops::Add<Point,Point> for Point {
+impl ops::Add for Point {
+    type Output = Point;
+
     fn add(self, other: Point) -> Point {
         Point {x: self.x + other.x, y: self.y + other.y}
     }
 }
 
-impl ops::Add<int,Point> for Point {
+impl ops::Add<int> for Point {
+    type Output = Point;
+
     fn add(self, other: int) -> Point {
         Point {x: self.x + other,
                y: self.y + other}
diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs
index 101b93c1896..b23133c53da 100644
--- a/src/test/run-pass/operator-overloading.rs
+++ b/src/test/run-pass/operator-overloading.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
 
 use std::cmp;
 use std::ops;
@@ -18,13 +19,17 @@ struct Point {
     y: int
 }
 
-impl ops::Add<Point,Point> for Point {
+impl ops::Add for Point {
+    type Output = Point;
+
     fn add(self, other: Point) -> Point {
         Point {x: self.x + other.x, y: self.y + other.y}
     }
 }
 
-impl ops::Sub<Point,Point> for Point {
+impl ops::Sub for Point {
+    type Output = Point;
+
     fn sub(self, other: Point) -> Point {
         Point {x: self.x - other.x, y: self.y - other.y}
     }
diff --git a/src/test/run-pass/overloaded-calls-param-vtables.rs b/src/test/run-pass/overloaded-calls-param-vtables.rs
index bdaccee65d7..b3c9ec3dc93 100644
--- a/src/test/run-pass/overloaded-calls-param-vtables.rs
+++ b/src/test/run-pass/overloaded-calls-param-vtables.rs
@@ -10,14 +10,14 @@
 
 // Tests that nested vtables work with overloaded calls.
 
-#![feature(unboxed_closures)]
+#![feature(default_type_params, unboxed_closures)]
 
 use std::ops::Fn;
 use std::ops::Add;
 
 struct G<A>;
 
-impl<'a, A: Add<int, int>> Fn<(A,), int> for G<A> {
+impl<'a, A: Add<int, Output=int>> Fn<(A,), int> for G<A> {
     extern "rust-call" fn call(&self, (arg,): (A,)) -> int {
         arg.add(1)
     }
diff --git a/src/test/run-pass/simd-generics.rs b/src/test/run-pass/simd-generics.rs
index 42f93a97142..ceb6b790426 100644
--- a/src/test/run-pass/simd-generics.rs
+++ b/src/test/run-pass/simd-generics.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-#![feature(simd)]
+#![feature(associated_types, simd)]
 
 use std::ops;
 
@@ -17,11 +17,13 @@ use std::ops;
 
 impl Copy for f32x4 {}
 
-fn add<T: ops::Add<T, T>>(lhs: T, rhs: T) -> T {
+fn add<T: ops::Add<Output=T>>(lhs: T, rhs: T) -> T {
     lhs + rhs
 }
 
-impl ops::Add<f32x4, f32x4> for f32x4 {
+impl ops::Add for f32x4 {
+    type Output = f32x4;
+
     fn add(self, rhs: f32x4) -> f32x4 {
         self + rhs
     }
diff --git a/src/test/run-pass/supertrait-default-generics.rs b/src/test/run-pass/supertrait-default-generics.rs
index 4465561f874..f31d9ca186f 100644
--- a/src/test/run-pass/supertrait-default-generics.rs
+++ b/src/test/run-pass/supertrait-default-generics.rs
@@ -17,7 +17,7 @@ trait Positioned<S> {
   fn X(&self) -> S;
 }
 
-trait Movable<S: Add<S, S>>: Positioned<S> {
+trait Movable<S: Add<Output=S>>: Positioned<S> {
   fn translate(&mut self, dx: S) {
     let x = self.X() + dx;
     self.SetX(x);
@@ -35,7 +35,7 @@ impl<S: Clone> Positioned<S> for Point<S> {
     }
 }
 
-impl<S: Clone + Add<S, S>> Movable<S> for Point<S> {}
+impl<S: Clone + Add<Output=S>> Movable<S> for Point<S> {}
 
 pub fn main() {
     let mut p = Point{ x: 1i, y: 2i};
diff --git a/src/test/run-pass/trait-inheritance-overloading.rs b/src/test/run-pass/trait-inheritance-overloading.rs
index 3748a31b302..3e8db61b940 100644
--- a/src/test/run-pass/trait-inheritance-overloading.rs
+++ b/src/test/run-pass/trait-inheritance-overloading.rs
@@ -8,23 +8,31 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(associated_types)]
+
 use std::cmp::PartialEq;
 use std::ops::{Add, Sub, Mul};
 
-trait MyNum : Add<Self,Self> + Sub<Self,Self> + Mul<Self,Self> + PartialEq + Clone { }
+trait MyNum : Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + PartialEq + Clone { }
 
 #[derive(Clone, Show)]
 struct MyInt { val: int }
 
-impl Add<MyInt, MyInt> for MyInt {
+impl Add for MyInt {
+    type Output = MyInt;
+
     fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) }
 }
 
-impl Sub<MyInt, MyInt> for MyInt {
+impl Sub for MyInt {
+    type Output = MyInt;
+
     fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) }
 }
 
-impl Mul<MyInt, MyInt> for MyInt {
+impl Mul for MyInt {
+    type Output = MyInt;
+
     fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) }
 }