rustc: Use coherence for operator overloading.

The only use of the old-style impls is now placement new.
This commit is contained in:
Patrick Walton 2012-07-27 19:32:42 -07:00
parent e6d2e49852
commit 93c2f5e0e4
23 changed files with 348 additions and 295 deletions

View file

@ -1,25 +1,30 @@
type point = { x: int, y: int };
trait add_and_times {
pure fn +(z: int) -> int;
fn *(z: int) -> int;
struct Point {
x: int;
y: int;
}
impl foo of add_and_times for point {
pure fn +(z: int) -> int { self.x + self.y + z }
fn *(z: int) -> int { self.x * self.y * z }
impl Point : ops::add<int,int> {
pure fn add(&&z: int) -> int {
self.x + self.y + z
}
}
impl Point {
fn times(z: int) -> int {
self.x * self.y * z
}
}
fn a() {
let mut p = {x: 3, y: 4};
let mut p = Point {x: 3, y: 4};
// ok (we can loan out rcvr)
p + 3;
p * 3;
p.times(3);
}
fn b() {
let mut p = {x: 3, y: 4};
let mut p = Point {x: 3, y: 4};
// Here I create an outstanding loan and check that we get conflicts:
@ -27,20 +32,20 @@ fn b() {
//~^ NOTE prior loan as mutable granted here
p + 3; //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
p * 3; //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
p.times(3); //~ ERROR loan of mutable local variable as immutable conflicts with prior loan
}
fn c() {
// Here the receiver is in aliased memory and hence we cannot
// consider it immutable:
let q = @mut {x: 3, y: 4};
let q = @mut Point {x: 3, y: 4};
// ...this is ok for pure fns
*q + 3;
// ...but not impure fns
*q * 3; //~ ERROR illegal borrow unless pure: creating immutable alias to aliasable, mutable memory
(*q).times(3); //~ ERROR illegal borrow unless pure: creating immutable alias to aliasable, mutable memory
//~^ NOTE impure due to access to impure function
}

View file

@ -1,6 +0,0 @@
// error-pattern:unresolved name: debug
#[no_core];
fn main() {
log(debug, 0);
}

View file

@ -1,33 +0,0 @@
type point = { x: int, y: int };
trait operators {
pure fn +(z: int) -> int;
fn *(z: int) -> int;
fn [](z: int) -> int;
fn unary-() -> int;
}
impl foo of operators for point {
// expr_binary
pure fn +(z: int) -> int { self.x + self.y + z }
fn *(z: int) -> int { self.x * self.y * z }
// expr_index
fn [](z: int) -> int { self.x * self.y * z }
// expr_unary
fn unary-() -> int { -(self.x * self.y) }
}
pure fn a(p: point) -> int { p + 3 }
pure fn b(p: point) -> int { p * 3 }
//~^ ERROR access to impure function prohibited in pure context
pure fn c(p: point) -> int { p[3] }
//~^ ERROR access to impure function prohibited in pure context
pure fn d(p: point) -> int { -p }
//~^ ERROR access to impure function prohibited in pure context
fn main() {}

View file

@ -1,12 +1,12 @@
iface add {
fn +(++x: self) -> self;
fn plus(++x: self) -> self;
}
impl of add for int {
fn +(++x: int) -> int { self + x }
fn plus(++x: int) -> int { self + x }
}
fn do_add<A:add>(x: A, y: A) -> A { x + y }
fn do_add<A:add>(x: A, y: A) -> A { x.plus(y) }
fn main() {
let x = 3 as add;

View file

@ -1,9 +1,9 @@
iface add {
fn +(x: self) -> self;
fn plus(x: self) -> self;
}
fn do_add(x: add, y: add) -> add {
x + y //~ ERROR can not call a method that contains a self type through a boxed iface
x.plus(y) //~ ERROR can not call a method that contains a self type through a boxed iface
}
fn main() {}