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 Default for BTreeSet { } #[stable] -impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet, BTreeSet> for &'a BTreeSet { +impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet> for &'a BTreeSet { + type Output = BTreeSet; + /// Returns the difference of `self` and `rhs` as a new `BTreeSet`. /// /// # Examples @@ -483,7 +485,9 @@ impl<'a, 'b, T: Ord + Clone> Sub<&'b BTreeSet, BTreeSet> for &'a BTreeSet< } #[stable] -impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet, BTreeSet> for &'a BTreeSet { +impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet> for &'a BTreeSet { + type Output = BTreeSet; + /// Returns the symmetric difference of `self` and `rhs` as a new `BTreeSet`. /// /// # Examples @@ -504,7 +508,9 @@ impl<'a, 'b, T: Ord + Clone> BitXor<&'b BTreeSet, BTreeSet> for &'a BTreeS } #[stable] -impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet, BTreeSet> for &'a BTreeSet { +impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet> for &'a BTreeSet { + type Output = BTreeSet; + /// Returns the intersection of `self` and `rhs` as a new `BTreeSet`. /// /// # Examples @@ -525,7 +531,9 @@ impl<'a, 'b, T: Ord + Clone> BitAnd<&'b BTreeSet, BTreeSet> for &'a BTreeS } #[stable] -impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet, BTreeSet> for &'a BTreeSet { +impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet> for &'a BTreeSet { + type Output = BTreeSet; + /// Returns the union of `self` and `rhs` as a new `BTreeSet`. /// /// # 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 EnumSet { } } -impl Sub, EnumSet> for EnumSet { +impl Sub for EnumSet { + type Output = EnumSet; + fn sub(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits & !e.bits} } } -impl BitOr, EnumSet> for EnumSet { +impl BitOr for EnumSet { + type Output = EnumSet; + fn bitor(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits | e.bits} } } -impl BitAnd, EnumSet> for EnumSet { +impl BitAnd for EnumSet { + type Output = EnumSet; + fn bitand(self, e: EnumSet) -> EnumSet { EnumSet {bits: self.bits & e.bits} } } -impl BitXor, EnumSet> for EnumSet { +impl BitXor for EnumSet { + type Output = EnumSet; + fn bitxor(self, e: EnumSet) -> EnumSet { 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 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 AsSlice for Vec { } } -impl<'a, T: Clone> Add<&'a [T], Vec> for Vec { +impl<'a, T: Clone> Add<&'a [T]> for Vec { + type Output = Vec; + #[inline] fn add(mut self, rhs: &[T]) -> Vec { 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(start: A, step: A) -> Counter { } #[unstable = "trait is unstable"] -impl + Clone> Iterator for Counter { +impl + Clone> Iterator for Counter { 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 + Rem>(x: T, y: T) -> (T, T) { +pub fn div_rem + Rem>(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 - + Sub - + Mul - + Div - + Rem + + Add + + Sub + + Mul + + Div + + Rem + Not - + BitAnd - + BitOr - + BitXor - + Shl - + Shr + + BitAnd + + BitOr + + BitXor + + Shl + + Shr { /// 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 - + Add - + Sub - + Mul - + Div - + Rem + + Add + + Sub + + Mul + + Div + + Rem { /// Returns the NaN value. fn nan() -> Self; @@ -1719,11 +1719,11 @@ macro_rules! trait_impl { #[allow(deprecated)] pub trait Num: PartialEq + Zero + One + Neg - + Add - + Sub - + Mul - + Div - + Rem {} + + Add + + Sub + + Mul + + Div + + Rem {} 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 { +pub trait Zero: Add { #[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 { +pub trait One: Mul { #[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 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 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 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 { +pub trait Add { + 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 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 { +pub trait Sub { + 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 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 { +pub trait Mul { + 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 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 { +pub trait Div { + 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 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 { +pub trait Rem { + 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 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 { +pub trait BitAnd { + 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 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 { +pub trait BitOr { + 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 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 { +pub trait BitXor { + 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 for Foo { +/// impl Shl 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 { +pub trait Shl { + 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 for $t { + impl Shl 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 for Foo { +/// impl Shr 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 { +pub trait Shr { + 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 for $t { + impl Shr 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(ten: T, two: T) where T: PartialEq + NumCast - + Add + Sub - + Mul + Div - + Rem + Show + + Add + Sub + + Mul + Div + + Rem + 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 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 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 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 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, S, H: Hasher + Default> Default for HashSet { #[stable] impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> -BitOr<&'b HashSet, HashSet> for &'a HashSet { +BitOr<&'b HashSet> for &'a HashSet { + type Output = HashSet; + /// Returns the union of `self` and `rhs` as a new `HashSet`. /// /// # Examples @@ -658,7 +660,9 @@ BitOr<&'b HashSet, HashSet> for &'a HashSet { #[stable] impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> -BitAnd<&'b HashSet, HashSet> for &'a HashSet { +BitAnd<&'b HashSet> for &'a HashSet { + type Output = HashSet; + /// Returns the intersection of `self` and `rhs` as a new `HashSet`. /// /// # Examples @@ -686,7 +690,9 @@ BitAnd<&'b HashSet, HashSet> for &'a HashSet { #[stable] impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> -BitXor<&'b HashSet, HashSet> for &'a HashSet { +BitXor<&'b HashSet> for &'a HashSet { + type Output = HashSet; + /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet`. /// /// # Examples @@ -714,7 +720,9 @@ BitXor<&'b HashSet, HashSet> for &'a HashSet { #[stable] impl<'a, 'b, T: Eq + Hash + Clone, S, H: Hasher + Default> -Sub<&'b HashSet, HashSet> for &'a HashSet { +Sub<&'b HashSet> for &'a HashSet { + type Output = HashSet; + /// Returns the difference of `self` and `rhs` as a new `HashSet`. /// /// # 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(x: T, y: T) -> T { #[cfg(test)] pub fn test_num(ten: T, two: T) where T: PartialEq + NumCast - + Add + Sub - + Mul + Div - + Rem + Show + + Add + Sub + + Mul + Div + + Rem + 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 for Duration { } } -impl Add 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 for Duration { } } -impl Sub 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 for Duration { } } -impl Mul for Duration { +impl Mul 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 for Duration { } } -impl Div for Duration { +impl Div 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 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 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 for CharPos { +impl Add for CharPos { + type Output = CharPos; + fn add(self, rhs: CharPos) -> CharPos { CharPos(self.to_uint() + rhs.to_uint()) } } -impl Sub 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 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 for Timespec { +impl Add 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 for Timespec { } } -impl Sub 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 + Sub + Mul + PartialEq + Clone { +pub trait MyNum : Add + Sub + Mul + PartialEq + Clone { } #[derive(Clone, Show)] @@ -19,15 +21,21 @@ pub struct MyInt { pub val: int } -impl Add for MyInt { +impl Add for MyInt { + type Output = MyInt; + fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) } } -impl Sub for MyInt { +impl Sub for MyInt { + type Output = MyInt; + fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) } } -impl Mul 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 + Copy>(x: T, y: T) -> T { +pub fn has_generic_closures + 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, B>(lhs: A, rhs: B) { +fn add, 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, B>(lhs: A, rhs: B) { +fn sub, 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, B>(lhs: A, rhs: B) { +fn mul, 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, B>(lhs: A, rhs: B) { +fn div, 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, B>(lhs: A, rhs: B) { +fn rem, 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, B>(lhs: A, rhs: B) { +fn bitand, 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, B>(lhs: A, rhs: B) { +fn bitor, 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, B>(lhs: A, rhs: B) { +fn bitxor, 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, B>(lhs: A, rhs: B) { +fn shl, 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, B>(lhs: A, rhs: B) { +fn shr, 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>(x: T) { +fn double_move>(x: T) { x + x; //~ ERROR: use of moved value } -fn move_then_borrow + Clone>(x: T) { +fn move_then_borrow + Clone>(x: T) { x + x.clone(); //~ ERROR: use of moved value } -fn move_borrowed>(x: T, mut y: T) { +fn move_borrowed>(x: T, mut y: T) { let m = &x; let n = &mut y; @@ -33,7 +35,7 @@ fn move_borrowed>(x: T, mut y: T) { y; //~ ERROR: cannot move out of `y` because it is borrowed } -fn illegal_dereference>(mut x: T, y: T) { +fn illegal_dereference>(mut x: T, y: T) { let m = &mut x; let n = &y; @@ -44,11 +46,15 @@ fn illegal_dereference>(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); -impl Add 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 for Point { +impl Add 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 { fn bind(&self, f: |A| -> Vec ); } 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 for Vec1 { +impl Mul 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 for Vec2 { +impl Mul 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 for Vec3 { +impl Mul 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); -impl> Add, Vector2> for Vector2 { +impl> Add for Vector2 { + type Output = Vector2; + fn add(self, other: Vector2) -> Vector2 { match (self, other) { (Vector2(x0, y0), Vector2(x1, y1)) => { @@ -29,7 +33,9 @@ struct Vector3 { x: T, y: T, z: T, } -impl> Add, Vector3> for Vector3 { +impl> Add for Vector3 { + type Output = Vector3; + fn add(self, other: Vector3) -> Vector3 { Vector3 { x: self.x + other.x, @@ -46,7 +52,9 @@ struct Matrix3x2 { z: Vector2, } -impl> Add, Matrix3x2> for Matrix3x2 { +impl> Add for Matrix3x2 { + type Output = Matrix3x2; + fn add(self, other: Matrix3x2) -> Matrix3x2 { 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 { fn mul_vec2_by(&self, lhs: &Vec2) -> Result; } // Vec2's implementation of Mul "from the other side" using the above trait -impl> Mul for Vec2 { +impl> Mul 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 { fn X(&self) -> S; } -trait Movable>: Positioned { +trait Movable>: Positioned { 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 + Clone>([x, y, z]: [T; 3]) -> (T, T, T) { +fn foo + 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 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 for Point { +impl ops::Add 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 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 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; -impl<'a, A: Add> Fn<(A,), int> for G { +impl<'a, A: Add> Fn<(A,), int> for G { 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>(lhs: T, rhs: T) -> T { +fn add>(lhs: T, rhs: T) -> T { lhs + rhs } -impl ops::Add 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 { fn X(&self) -> S; } -trait Movable>: Positioned { +trait Movable>: Positioned { fn translate(&mut self, dx: S) { let x = self.X() + dx; self.SetX(x); @@ -35,7 +35,7 @@ impl Positioned for Point { } } -impl> Movable for Point {} +impl> Movable for Point {} 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 + Sub + Mul + PartialEq + Clone { } +trait MyNum : Add + Sub + Mul + PartialEq + Clone { } #[derive(Clone, Show)] struct MyInt { val: int } -impl Add for MyInt { +impl Add for MyInt { + type Output = MyInt; + fn add(self, other: MyInt) -> MyInt { mi(self.val + other.val) } } -impl Sub for MyInt { +impl Sub for MyInt { + type Output = MyInt; + fn sub(self, other: MyInt) -> MyInt { mi(self.val - other.val) } } -impl Mul for MyInt { +impl Mul for MyInt { + type Output = MyInt; + fn mul(self, other: MyInt) -> MyInt { mi(self.val * other.val) } }