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

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