use assoc types in binop traits

This commit is contained in:
Jorge Aparicio 2014-12-31 15:45:13 -05:00
parent 7095dd0070
commit 99017f82b6
36 changed files with 375 additions and 156 deletions

View File

@ -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

View File

@ -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}
}

View File

@ -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

View File

@ -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);

View File

@ -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]

View File

@ -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;
}

View File

@ -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 }
}

View File

@ -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());

View File

@ -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}
}

View File

@ -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;

View File

@ -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,

View File

@ -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 {

View File

@ -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

View File

@ -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());

View File

@ -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;

View File

@ -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())
}

View File

@ -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,

View File

@ -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;

View File

@ -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) }
}

View File

@ -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()

View File

@ -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`

View File

@ -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) {}
}

View File

@ -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;

View File

@ -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
}

View File

@ -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> );
}

View File

@ -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

View File

@ -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,

View File

@ -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) }
}

View File

@ -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);

View File

@ -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] {

View File

@ -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}

View File

@ -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}
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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};

View File

@ -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) }
}