diff --git a/doc/rust.md b/doc/rust.md index ac7125be424d4..60848441e4e77 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1946,35 +1946,6 @@ fn avg(v: &[float]) -> float { } ~~~~ -#### Swap expressions - -A _swap expression_ consists of an [lvalue](#lvalues-rvalues-and-temporaries) followed by a bi-directional arrow (`<->`) and another [lvalue](#lvalues-rvalues-and-temporaries). - -Evaluating a swap expression causes, as a side effect, the values held in the left-hand-side and right-hand-side [lvalues](#lvalues-rvalues-and-temporaries) to be exchanged indivisibly. - -Evaluating a swap expression neither changes reference counts, -nor deeply copies any owned structure pointed to by the moved [rvalue](#lvalues-rvalues-and-temporaries). -Instead, the swap expression represents an indivisible *exchange of ownership*, -between the right-hand-side and the left-hand-side of the expression. -No allocation or destruction is entailed. - -An example of three different swap expressions: - -~~~~~~~~ -# let mut x = &mut [0]; -# let mut a = &mut [0]; -# let i = 0; -# struct S1 { z: int }; -# struct S2 { c: int }; -# let mut y = S1{z: 0}; -# let mut b = S2{c: 0}; - -x <-> a; -x[i] <-> a[i]; -y.z <-> b.c; -~~~~~~~~ - - #### Assignment expressions An _assignment expression_ consists of an [lvalue](#lvalues-rvalues-and-temporaries) expression followed by an @@ -2015,7 +1986,7 @@ as == != && || -= <-> += ~~~~ Operators at the same precedence level are evaluated left-to-right. diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md index 2a3d8dc14817c..d8367fbdc2d79 100644 --- a/doc/tutorial-ffi.md +++ b/doc/tutorial-ffi.md @@ -151,6 +151,7 @@ wrapping `malloc` and `free`: ~~~~ use core::libc::{c_void, size_t, malloc, free}; use core::unstable::intrinsics; +use core::util; // a wrapper around the handle returned by the foreign code pub struct Unique { @@ -184,7 +185,8 @@ impl Drop for Unique { fn finalize(&self) { unsafe { let mut x = intrinsics::init(); // dummy value to swap in - x <-> *self.ptr; // moving the object out is needed to call the destructor + // moving the object out is needed to call the destructor + util::replace_ptr(self.ptr, x); free(self.ptr as *c_void) } } diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c7f9e37757139..18e75fb1aa98e 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -12,6 +12,7 @@ use cast::transmute_mut; use prelude::*; +use util::replace; /* A dynamic, mutable location. @@ -48,9 +49,7 @@ pub impl Cell { fail!(~"attempt to take an empty cell"); } - let mut value = None; - value <-> self.value; - value.unwrap() + replace(&mut self.value, None).unwrap() } /// Returns the value, failing if the cell is full. diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 7eaa853549336..140eb41fdf3d6 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -21,6 +21,7 @@ use uint; use unstable; use vec; use unstable::Exclusive; +use util::replace; use pipes::{recv, try_recv, wait_many, peek, PacketHeader}; @@ -149,9 +150,8 @@ impl GenericChan for Chan { #[inline(always)] fn send(&self, x: T) { unsafe { - let mut endp = None; let mut self_endp = transmute_mut(&self.endp); - endp <-> *self_endp; + let endp = replace(self_endp, None); *self_endp = Some(streamp::client::data(endp.unwrap(), x)) } } @@ -161,9 +161,8 @@ impl GenericSmartChan for Chan { #[inline(always)] fn try_send(&self, x: T) -> bool { unsafe { - let mut endp = None; let mut self_endp = transmute_mut(&self.endp); - endp <-> *self_endp; + let endp = replace(self_endp, None); match streamp::client::try_data(endp.unwrap(), x) { Some(next) => { *self_endp = Some(next); @@ -179,9 +178,8 @@ impl GenericPort for Port { #[inline(always)] fn recv(&self) -> T { unsafe { - let mut endp = None; let mut self_endp = transmute_mut(&self.endp); - endp <-> *self_endp; + let endp = replace(self_endp, None); let streamp::data(x, endp) = recv(endp.unwrap()); *self_endp = Some(endp); x @@ -191,9 +189,8 @@ impl GenericPort for Port { #[inline(always)] fn try_recv(&self) -> Option { unsafe { - let mut endp = None; let mut self_endp = transmute_mut(&self.endp); - endp <-> *self_endp; + let endp = replace(self_endp, None); match try_recv(endp.unwrap()) { Some(streamp::data(x, endp)) => { *self_endp = Some(endp); @@ -209,14 +206,13 @@ impl Peekable for Port { #[inline(always)] fn peek(&self) -> bool { unsafe { - let mut endp = None; let mut self_endp = transmute_mut(&self.endp); - endp <-> *self_endp; + let mut endp = replace(self_endp, None); let peek = match endp { Some(ref mut endp) => peek(endp), None => fail!(~"peeking empty stream") }; - *self_endp <-> endp; + *self_endp = endp; peek } } @@ -267,8 +263,7 @@ impl GenericPort for PortSet { let mut result = None; // we have to swap the ports array so we aren't borrowing // aliasable mutable memory. - let mut ports = ~[]; - ports <-> *self_ports; + let mut ports = replace(self_ports, ~[]); while result.is_none() && ports.len() > 0 { let i = wait_many(ports); match ports[i].try_recv() { @@ -281,7 +276,7 @@ impl GenericPort for PortSet { } } } - ports <-> *self_ports; + *self_ports = ports; result } } @@ -320,8 +315,7 @@ impl GenericChan for SharedChan { fn send(&self, x: T) { let mut xx = Some(x); do self.ch.with_imm |chan| { - let mut x = None; - x <-> xx; + let x = replace(&mut xx, None); chan.send(x.unwrap()) } } @@ -331,8 +325,7 @@ impl GenericSmartChan for SharedChan { fn try_send(&self, x: T) -> bool { let mut xx = Some(x); do self.ch.with_imm |chan| { - let mut x = None; - x <-> xx; + let x = replace(&mut xx, None); chan.try_send(x.unwrap()) } } diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs index b5ae07208fc66..590d4ab3bcb40 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -176,16 +176,13 @@ priv impl HashMap { /// Expands the capacity of the array and re-insert each of the /// existing buckets. fn resize(&mut self, new_capacity: uint) { - let old_capacity = self.buckets.len(); self.resize_at = resize_at(new_capacity); - let mut old_buckets = vec::from_fn(new_capacity, |_| None); - self.buckets <-> old_buckets; + let old_buckets = replace(&mut self.buckets, + vec::from_fn(new_capacity, |_| None)); self.size = 0; - for uint::range(0, old_capacity) |i| { - let mut bucket = None; - bucket <-> old_buckets[i]; + do vec::consume(old_buckets) |_, bucket| { self.insert_opt_bucket(bucket); } } @@ -265,13 +262,11 @@ priv impl HashMap { }; let len_buckets = self.buckets.len(); - let mut bucket = None; - self.buckets[idx] <-> bucket; + let bucket = replace(&mut self.buckets[idx], None); let value = match bucket { None => None, - Some(bucket) => { - let Bucket{value: value, _} = bucket; + Some(Bucket{value, _}) => { Some(value) }, }; @@ -281,8 +276,7 @@ priv impl HashMap { let size = self.size - 1; idx = self.next_bucket(idx, len_buckets); while self.buckets[idx].is_some() { - let mut bucket = None; - bucket <-> self.buckets[idx]; + let bucket = replace(&mut self.buckets[idx], None); self.insert_opt_bucket(bucket); idx = self.next_bucket(idx, len_buckets); } @@ -613,15 +607,13 @@ pub impl HashMap { } fn consume(&mut self, f: &fn(K, V)) { - let mut buckets = ~[]; - self.buckets <-> buckets; + let buckets = replace(&mut self.buckets, ~[]); self.size = 0; do vec::consume(buckets) |_, bucket| { match bucket { None => {}, - Some(bucket) => { - let Bucket{key: key, value: value, _} = bucket; + Some(Bucket{key, value, _}) => { f(key, value) } } diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index 8301254fbdd18..fe9c78198bb13 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -93,6 +93,7 @@ use unstable::intrinsics; use ptr; use task; use vec; +use util::replace; static SPIN_COUNT: uint = 0; @@ -428,8 +429,7 @@ fn try_recv_(p: &mut Packet) -> Option { // optimistic path match p.header.state { Full => { - let mut payload = None; - payload <-> p.payload; + let payload = replace(&mut p.payload, None); p.header.state = Empty; return Some(payload.unwrap()) }, @@ -480,8 +480,7 @@ fn try_recv_(p: &mut Packet) -> Option { fail!(~"blocking on already blocked packet") }, Full => { - let mut payload = None; - payload <-> p.payload; + let payload = replace(&mut p.payload, None); let old_task = swap_task(&mut p.header.blocked_task, ptr::null()); if !old_task.is_null() { unsafe { @@ -675,8 +674,7 @@ impl Drop for SendPacketBuffered { unsafe { let this: &mut SendPacketBuffered = transmute(self); if this.p != None { - let mut p = None; - p <-> this.p; + let p = replace(&mut this.p, None); sender_terminate(p.unwrap()) } } @@ -695,9 +693,7 @@ pub fn SendPacketBuffered(p: *mut Packet) pub impl SendPacketBuffered { fn unwrap(&mut self) -> *mut Packet { - let mut p = None; - p <-> self.p; - p.unwrap() + replace(&mut self.p, None).unwrap() } fn header(&mut self) -> *mut PacketHeader { @@ -713,9 +709,7 @@ pub impl SendPacketBuffered { fn reuse_buffer(&mut self) -> BufferResource { //error!("send reuse_buffer"); - let mut tmp = None; - tmp <-> self.buffer; - tmp.unwrap() + replace(&mut self.buffer, None).unwrap() } } @@ -738,8 +732,7 @@ impl Drop for RecvPacketBuffered { unsafe { let this: &mut RecvPacketBuffered = transmute(self); if this.p != None { - let mut p = None; - p <-> this.p; + let p = replace(&mut this.p, None); receiver_terminate(p.unwrap()) } } @@ -748,15 +741,11 @@ impl Drop for RecvPacketBuffered { pub impl RecvPacketBuffered { fn unwrap(&mut self) -> *mut Packet { - let mut p = None; - p <-> self.p; - p.unwrap() + replace(&mut self.p, None).unwrap() } fn reuse_buffer(&mut self) -> BufferResource { - let mut tmp = None; - tmp <-> self.buffer; - tmp.unwrap() + replace(&mut self.buffer, None).unwrap() } } diff --git a/src/libcore/util.rs b/src/libcore/util.rs index 43616ebfd3032..db9a17cf97ffe 100644 --- a/src/libcore/util.rs +++ b/src/libcore/util.rs @@ -15,6 +15,7 @@ Miscellaneous helpers for common patterns. */ use prelude::*; +use unstable::intrinsics; /// The identity function. #[inline(always)] @@ -34,12 +35,12 @@ pub fn ignore(_x: T) { } #[inline(always)] pub fn with( ptr: @mut T, - mut value: T, + value: T, op: &fn() -> R) -> R { - value <-> *ptr; + let prev = replace(ptr, value); let result = op(); - *ptr = value; + *ptr = prev; return result; } @@ -49,7 +50,65 @@ pub fn with( */ #[inline(always)] pub fn swap(x: &mut T, y: &mut T) { - *x <-> *y; + unsafe { + swap_ptr(ptr::to_mut_unsafe_ptr(x), ptr::to_mut_unsafe_ptr(y)); + } +} + +/** + * Swap the values at two mutable locations of the same type, without + * deinitialising or copying either one. + */ +#[inline] +#[cfg(not(stage0))] +pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { + if x == y { return } + + // Give ourselves some scratch space to work with + let mut tmp: T = intrinsics::uninit(); + let t = ptr::to_mut_unsafe_ptr(&mut tmp); + + // Perform the swap + ptr::copy_memory(t, x, 1); + ptr::copy_memory(x, y, 1); + ptr::copy_memory(y, t, 1); + + // y and t now point to the same thing, but we need to completely forget t + // because it's no longer relevant. + cast::forget(tmp); +} + +/** + * Swap the values at two mutable locations of the same type, without + * deinitialising or copying either one. + */ +#[inline] +#[cfg(stage0)] +pub unsafe fn swap_ptr(x: *mut T, y: *mut T) { + if x == y { return } + + // Give ourselves some scratch space to work with + let mut tmp: T = intrinsics::init(); + let t = ptr::to_mut_unsafe_ptr(&mut tmp); + + // Perform the swap + ptr::copy_memory(t, x, 1); + ptr::copy_memory(x, y, 1); + ptr::copy_memory(y, t, 1); + + // y and t now point to the same thing, but we need to completely forget t + // because it's no longer relevant. + cast::forget(tmp); +} + +/** + * Replace the value at a mutable location with a new one, returning the old + * value, without deinitialising or copying either one. + */ +#[inline(always)] +pub fn replace(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src } /** @@ -57,10 +116,9 @@ pub fn swap(x: &mut T, y: &mut T) { * value, without deinitialising or copying either one. */ #[inline(always)] -pub fn replace(dest: &mut T, src: T) -> T { - let mut tmp = src; - swap(dest, &mut tmp); - tmp +pub unsafe fn replace_ptr(dest: *mut T, mut src: T) -> T { + swap_ptr(dest, ptr::to_mut_unsafe_ptr(&mut src)); + src } /// A non-copyable dummy type. diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 7eba2cbf0ccc4..77314b173d981 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -29,6 +29,7 @@ use sys; use uint; use unstable::intrinsics; use vec; +use util; #[cfg(not(test))] use cmp::Equiv; @@ -470,7 +471,7 @@ pub fn shift(v: &mut ~[T]) -> T { let next_ln = v.len() - 1; // Save the last element. We're going to overwrite its position - let mut work_elt = v.pop(); + let work_elt = v.pop(); // We still should have room to work where what last element was assert!(capacity(v) >= ln); // Pretend like we have the original length so we can use @@ -501,16 +502,14 @@ pub fn shift(v: &mut ~[T]) -> T { // Swap out the element we want from the end let vp = raw::to_mut_ptr(*v); let vp = ptr::mut_offset(vp, next_ln - 1); - *vp <-> work_elt; - work_elt + util::replace_ptr(vp, work_elt) } } /// Prepend an element to the vector pub fn unshift(v: &mut ~[T], x: T) { - let mut vv = ~[x]; - *v <-> vv; + let vv = util::replace(v, ~[x]); v.push_all_move(vv); } @@ -523,7 +522,7 @@ pub fn insert(v: &mut ~[T], i: uint, x: T) { v.push(x); let mut j = len; while j > i { - v[j] <-> v[j - 1]; + swap(*v, j, j - 1); j -= 1; } } @@ -536,7 +535,7 @@ pub fn remove(v: &mut ~[T], i: uint) -> T { let mut j = i; while j < len - 1 { - v[j] <-> v[j + 1]; + swap(*v, j, j + 1); j += 1; } v.pop() @@ -550,10 +549,9 @@ pub fn consume(mut v: ~[T], f: &fn(uint, v: T)) { // holes we create in the vector. That ensures that, if the // iterator fails then we won't try to clean up the consumed // elements during unwinding - let mut x = intrinsics::init(); + let x = intrinsics::init(); let p = ptr::mut_offset(p, i); - x <-> *p; - f(i, x); + f(i, util::replace_ptr(p, x)); } } @@ -572,10 +570,9 @@ pub fn consume_reverse(mut v: ~[T], f: &fn(uint, v: T)) { // holes we create in the vector. That ensures that, if the // iterator fails then we won't try to clean up the consumed // elements during unwinding - let mut x = intrinsics::init(); + let x = intrinsics::init(); let p = ptr::mut_offset(p, i); - x <-> *p; - f(i, x); + f(i, util::replace_ptr(p, x)); } } @@ -592,8 +589,7 @@ pub fn pop(v: &mut ~[T]) -> T { } let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]); unsafe { - let mut val = intrinsics::uninit(); - val <-> *valptr; + let val = util::replace_ptr(valptr, intrinsics::uninit()); raw::set_len(v, ln - 1u); val } @@ -607,8 +603,7 @@ pub fn pop(v: &mut ~[T]) -> T { } let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]); unsafe { - let mut val = intrinsics::init(); - val <-> *valptr; + let val = util::replace_ptr(valptr, intrinsics::init()); raw::set_len(v, ln - 1u); val } @@ -626,7 +621,7 @@ pub fn swap_remove(v: &mut ~[T], index: uint) -> T { fail!(fmt!("vec::swap_remove - index %u >= length %u", index, ln)); } if index < ln - 1 { - v[index] <-> v[ln - 1]; + swap(*v, index, ln - 1); } v.pop() } @@ -682,8 +677,8 @@ pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { unsafe { do as_mut_buf(rhs) |p, len| { for uint::range(0, len) |i| { - let mut x = intrinsics::uninit(); - x <-> *ptr::mut_offset(p, i); + let x = util::replace_ptr(ptr::mut_offset(p, i), + intrinsics::uninit()); push(&mut *v, x); } } @@ -699,8 +694,8 @@ pub fn push_all_move(v: &mut ~[T], mut rhs: ~[T]) { unsafe { do as_mut_buf(rhs) |p, len| { for uint::range(0, len) |i| { - let mut x = intrinsics::init(); - x <-> *ptr::mut_offset(p, i); + let x = util::replace_ptr(ptr::mut_offset(p, i), + intrinsics::init()); push(&mut *v, x); } } @@ -716,8 +711,7 @@ pub fn truncate(v: &mut ~[T], newlen: uint) { unsafe { // This loop is optimized out for non-drop types. for uint::range(newlen, oldlen) |i| { - let mut dropped = intrinsics::uninit(); - dropped <-> *ptr::mut_offset(p, i); + util::replace_ptr(ptr::mut_offset(p, i), intrinsics::uninit()); } } } @@ -732,8 +726,7 @@ pub fn truncate(v: &mut ~[T], newlen: uint) { unsafe { // This loop is optimized out for non-drop types. for uint::range(newlen, oldlen) |i| { - let mut dropped = intrinsics::init(); - dropped <-> *ptr::mut_offset(p, i); + util::replace_ptr(ptr::mut_offset(p, i), intrinsics::init()); } } } @@ -758,14 +751,14 @@ pub fn dedup(v: &mut ~[T]) { // last_written < next_to_read < ln if *ptr::mut_offset(p, next_to_read) == *ptr::mut_offset(p, last_written) { - let mut dropped = intrinsics::uninit(); - dropped <-> *ptr::mut_offset(p, next_to_read); + util::replace_ptr(ptr::mut_offset(p, next_to_read), + intrinsics::uninit()); } else { last_written += 1; // last_written <= next_to_read < ln if next_to_read != last_written { - *ptr::mut_offset(p, last_written) <-> - *ptr::mut_offset(p, next_to_read); + util::swap_ptr(ptr::mut_offset(p, last_written), + ptr::mut_offset(p, next_to_read)); } } // last_written <= next_to_read < ln @@ -796,14 +789,14 @@ pub fn dedup(v: &mut ~[T]) { // last_written < next_to_read < ln if *ptr::mut_offset(p, next_to_read) == *ptr::mut_offset(p, last_written) { - let mut dropped = intrinsics::init(); - dropped <-> *ptr::mut_offset(p, next_to_read); + util::replace_ptr(ptr::mut_offset(p, next_to_read), + intrinsics::init()); } else { last_written += 1; // last_written <= next_to_read < ln if next_to_read != last_written { - *ptr::mut_offset(p, last_written) <-> - *ptr::mut_offset(p, next_to_read); + util::swap_ptr(ptr::mut_offset(p, last_written), + ptr::mut_offset(p, next_to_read)); } } // last_written <= next_to_read < ln @@ -1028,7 +1021,7 @@ pub fn retain(v: &mut ~[T], f: &fn(t: &T) -> bool) { if !f(&v[i]) { deleted += 1; } else if deleted > 0 { - v[i - deleted] <-> v[i]; + swap(*v, i - deleted, i); } } @@ -1429,15 +1422,25 @@ pub fn zip(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] { * * a - The index of the first element * * b - The index of the second element */ +#[inline(always)] pub fn swap(v: &mut [T], a: uint, b: uint) { - v[a] <-> v[b]; + unsafe { + // Can't take two mutable loans from one vector, so instead just cast + // them to their raw pointers to do the swap + let pa: *mut T = ptr::to_mut_unsafe_ptr(&mut v[a]); + let pb: *mut T = ptr::to_mut_unsafe_ptr(&mut v[b]); + util::swap_ptr(pa, pb); + } } /// Reverse the order of elements in a vector, in place pub fn reverse(v: &mut [T]) { let mut i: uint = 0; let ln = len::(v); - while i < ln / 2 { v[i] <-> v[ln - i - 1]; i += 1; } + while i < ln / 2 { + swap(v, i, ln - i - 1); + i += 1; + } } /// Returns a vector with the order of elements reversed @@ -2476,6 +2479,7 @@ pub mod raw { use sys; use unstable::intrinsics; use vec::{UnboxedVecRepr, as_const_buf, as_mut_buf, len, with_capacity}; + use util; /// The internal representation of a (boxed) vector pub struct VecRepr { @@ -2573,8 +2577,7 @@ pub mod raw { pub unsafe fn init_elem(v: &mut [T], i: uint, val: T) { let mut box = Some(val); do as_mut_buf(v) |p, _len| { - let mut box2 = None; - box2 <-> box; + let box2 = util::replace(&mut box, None); intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), box2.unwrap()); } diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 27f6ae33ba3d1..2f116cb1b284b 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -758,10 +758,6 @@ fn check_loans_in_expr<'a>(expr: @ast::expr, } match expr.node { - ast::expr_swap(l, r) => { - self.check_assignment(l); - self.check_assignment(r); - } ast::expr_assign(dest, _) | ast::expr_assign_op(_, dest, _) => { self.check_assignment(dest); diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index f1fa5144f4c75..dc08fb39ad984 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -698,11 +698,6 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { self.walk_expr(l, in_out, loop_scopes); } - ast::expr_swap(l, r) => { - self.walk_expr(l, in_out, loop_scopes); - self.walk_expr(r, in_out, loop_scopes); - } - ast::expr_vec(ref exprs, _) => { self.walk_exprs(*exprs, in_out, loop_scopes) } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 0bd73a15d507c..52274f3d30570 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -523,7 +523,7 @@ fn visit_expr(expr: @expr, self: @mut IrMaps, vt: vt<@mut IrMaps>) { expr_binary(*) | expr_addr_of(*) | expr_copy(*) | expr_loop_body(*) | expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_break(_) | expr_again(_) | expr_lit(_) | expr_ret(*) | expr_block(*) | - expr_assign(*) | expr_swap(*) | expr_assign_op(*) | expr_mac(*) | + expr_assign(*) | expr_assign_op(*) | expr_mac(*) | expr_struct(*) | expr_repeat(*) | expr_paren(*) | expr_inline_asm(*) => { visit::visit_expr(expr, self, vt); @@ -1141,21 +1141,6 @@ pub impl Liveness { self.propagate_through_expr(r, succ) } - expr_swap(l, r) => { - // see comment on lvalues in - // propagate_through_lvalue_components() - - // I count swaps as `used` cause it might be something like: - // foo.bar <-> x - // and I am too lazy to distinguish this case from - // y <-> x - // (where both x, y are unused) just for a warning. - let succ = self.write_lvalue(r, succ, ACC_WRITE|ACC_READ|ACC_USE); - let succ = self.write_lvalue(l, succ, ACC_WRITE|ACC_READ|ACC_USE); - let succ = self.propagate_through_lvalue_components(r, succ); - self.propagate_through_lvalue_components(l, succ) - } - expr_assign_op(_, l, r) => { // see comment on lvalues in // propagate_through_lvalue_components() @@ -1533,7 +1518,7 @@ fn check_expr(expr: @expr, self: @Liveness, vt: vt<@Liveness>) { expr_vstore(*) | expr_vec(*) | expr_tup(*) | expr_log(*) | expr_binary(*) | expr_copy(*) | expr_loop_body(*) | expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) | - expr_again(*) | expr_lit(_) | expr_block(*) | expr_swap(*) | + expr_again(*) | expr_lit(_) | expr_block(*) | expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) | expr_paren(*) => { visit::visit_expr(expr, self, vt); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 0e819c66f094d..7675efa76f4be 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -413,7 +413,7 @@ pub impl mem_categorization_ctxt { ast::expr_paren(e) => self.cat_expr_unadjusted(e), - ast::expr_addr_of(*) | ast::expr_call(*) | ast::expr_swap(*) | + ast::expr_addr_of(*) | ast::expr_call(*) | ast::expr_assign(*) | ast::expr_assign_op(*) | ast::expr_fn_block(*) | ast::expr_ret(*) | ast::expr_loop_body(*) | ast::expr_do_body(*) | ast::expr_unary(*) | diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 040ff30f9e63f..2471e383bca9c 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -650,11 +650,6 @@ pub impl VisitContext { self.consume_expr(count, visitor); } - expr_swap(lhs, rhs) => { - self.use_expr(lhs, Read, visitor); - self.use_expr(rhs, Read, visitor); - } - expr_loop_body(base) | expr_do_body(base) => { self.use_expr(base, comp_mode, visitor); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 1b7cdf3ac8059..ed3dfdc07c373 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -528,33 +528,6 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { return src_datum.store_to_datum( bcx, src.id, DROP_EXISTING, dst_datum); } - ast::expr_swap(dst, src) => { - let dst_datum = unpack_datum!(bcx, trans_lvalue(bcx, dst)); - let src_datum = unpack_datum!(bcx, trans_lvalue(bcx, src)); - - // If the source and destination are the same, then don't swap. - // Avoids performing an overlapping memcpy - let dst_datum_ref = dst_datum.to_ref_llval(bcx); - let src_datum_ref = src_datum.to_ref_llval(bcx); - let cmp = ICmp(bcx, lib::llvm::IntEQ, - src_datum_ref, - dst_datum_ref); - - let swap_cx = base::sub_block(bcx, "swap"); - let next_cx = base::sub_block(bcx, "next"); - - CondBr(bcx, cmp, next_cx.llbb, swap_cx.llbb); - - let scratch = scratch_datum(swap_cx, dst_datum.ty, false); - - let swap_cx = dst_datum.move_to_datum(swap_cx, INIT, scratch); - let swap_cx = src_datum.move_to_datum(swap_cx, INIT, dst_datum); - let swap_cx = scratch.move_to_datum(swap_cx, INIT, src_datum); - - Br(swap_cx, next_cx.llbb); - - return next_cx; - } ast::expr_assign_op(op, dst, src) => { return trans_assign_op(bcx, expr, op, dst, src); } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index cbad7bcb3a6be..3c2738d3ae80e 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -314,7 +314,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) { } } } - expr_assign(val, _) | expr_swap(val, _) | expr_assign_op(_, val, _) | + expr_assign(val, _) | expr_assign_op(_, val, _) | expr_ret(Some(val)) => { node_type_needs(cx, use_repr, val.id); } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 737548ee86869..829a1e399de0c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3465,7 +3465,6 @@ pub fn expr_kind(tcx: ctxt, ast::expr_while(*) | ast::expr_loop(*) | ast::expr_assign(*) | - ast::expr_swap(*) | ast::expr_inline_asm(*) | ast::expr_assign_op(*) => { RvalueStmtExpr diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index baa28b6498278..7c79693a8b2eb 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2460,20 +2460,6 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_nil(id); } } - ast::expr_swap(lhs, rhs) => { - check_assignment(fcx, lhs, rhs, id); - let lhs_ty = fcx.expr_ty(lhs); - let rhs_ty = fcx.expr_ty(rhs); - if ty::type_is_error(lhs_ty) || ty::type_is_error(rhs_ty) { - fcx.write_error(id); - } - else if ty::type_is_bot(lhs_ty) || ty::type_is_bot(rhs_ty) { - fcx.write_bot(id); - } - else { - fcx.write_nil(id); - } - } ast::expr_if(cond, ref thn, elsopt) => { check_expr_has_type(fcx, cond, ty::mk_bool()); check_then_else(fcx, thn, elsopt, id, expr.span); diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 2274259f18c19..55c1f03b330e2 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -1016,7 +1016,6 @@ pub mod guarantor { ast::expr_while(*) | ast::expr_loop(*) | ast::expr_assign(*) | - ast::expr_swap(*) | ast::expr_assign_op(*) | ast::expr_cast(*) | ast::expr_call(*) | diff --git a/src/librusti/rusti.rc b/src/librusti/rusti.rc index a8cd7f5f41c66..836ca1cfa45b5 100644 --- a/src/librusti/rusti.rc +++ b/src/librusti/rusti.rc @@ -96,10 +96,6 @@ fn record(repl: Repl, blk: @ast::blk, intr: @token::ident_interner) -> Repl { match expr.node { ast::expr_assign(*) | ast::expr_assign_op(*) | - ast::expr_swap(*) => { - pprust::print_stmt(pp, *stmt); - writer.write_line(~""); - } _ => {} } } diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index 4eb359e48a84d..c94acaa1f70db 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -10,6 +10,8 @@ //! A double-ended queue implemented as a circular buffer +use core::util::replace; + static initial_capacity: uint = 32u; // 2^5 pub struct Deque { @@ -142,9 +144,7 @@ fn grow(nelts: uint, lo: uint, elts: &mut [Option]) -> ~[Option] { let mut rv = ~[]; do rv.grow_fn(nelts + 1) |i| { - let mut element = None; - element <-> elts[(lo + i) % nelts]; - element + replace(&mut elts[(lo + i) % nelts], None) } rv diff --git a/src/libstd/future.rs b/src/libstd/future.rs index b1b2fa2cd28e1..ac23ea1a6e2c2 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -26,6 +26,7 @@ use core::cell::Cell; use core::comm::{PortOne, oneshot, send_one}; use core::pipes::recv; use core::task; +use core::util::replace; #[doc = "The future type"] #[cfg(stage0)] @@ -77,8 +78,7 @@ pub impl Future { } } { - let mut state = Evaluating; - self.state <-> state; + let state = replace(&mut self.state, Evaluating); match state { Forced(_) | Evaluating => fail!(~"Logic error."), Pending(f) => { @@ -108,8 +108,7 @@ pub impl Future { } } { - let mut state = Evaluating; - self.state <-> state; + let state = replace(&mut self.state, Evaluating); match state { Forced(_) | Evaluating => fail!(~"Logic error."), Pending(f) => { diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index bdb93142472fb..ded632b29d94e 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -11,6 +11,7 @@ //! A priority queue implemented with a binary heap use core::old_iter::BaseIter; +use core::util::{replace, swap}; #[abi = "rust-intrinsic"] extern "rust-intrinsic" mod rusti { @@ -73,7 +74,10 @@ pub impl PriorityQueue { /// Pop the greatest item from the queue - fails if empty fn pop(&mut self) -> T { let mut item = self.data.pop(); - if !self.is_empty() { item <-> self.data[0]; self.siftdown(0); } + if !self.is_empty() { + swap(&mut item, &mut self.data[0]); + self.siftdown(0); + } item } @@ -92,7 +96,7 @@ pub impl PriorityQueue { /// Optimized version of a push followed by a pop fn push_pop(&mut self, mut item: T) -> T { if !self.is_empty() && self.data[0] > item { - item <-> self.data[0]; + swap(&mut item, &mut self.data[0]); self.siftdown(0); } item @@ -100,7 +104,7 @@ pub impl PriorityQueue { /// Optimized version of a pop followed by a push - fails if empty fn replace(&mut self, mut item: T) -> T { - item <-> self.data[0]; + swap(&mut item, &mut self.data[0]); self.siftdown(0); item } @@ -115,7 +119,7 @@ pub impl PriorityQueue { let mut end = q.len(); while end > 1 { end -= 1; - q.data[end] <-> q.data[0]; + vec::swap(q.data, 0, end); q.siftdown_range(0, end) } q.to_vec() @@ -149,8 +153,7 @@ pub impl PriorityQueue { while pos > start { let parent = (pos - 1) >> 1; if new > self.data[parent] { - let mut x = rusti::uninit(); - x <-> self.data[parent]; + let x = replace(&mut self.data[parent], rusti::uninit()); rusti::move_val_init(&mut self.data[pos], x); pos = parent; loop @@ -169,8 +172,7 @@ pub impl PriorityQueue { while pos > start { let parent = (pos - 1) >> 1; if new > self.data[parent] { - let mut x = rusti::init(); - x <-> self.data[parent]; + let x = replace(&mut self.data[parent], rusti::init()); rusti::move_val_init(&mut self.data[pos], x); pos = parent; loop @@ -194,8 +196,7 @@ pub impl PriorityQueue { if right < end && !(self.data[child] > self.data[right]) { child = right; } - let mut x = rusti::uninit(); - x <-> self.data[child]; + let x = replace(&mut self.data[child], rusti::uninit()); rusti::move_val_init(&mut self.data[pos], x); pos = child; child = 2 * pos + 1; @@ -218,8 +219,7 @@ pub impl PriorityQueue { if right < end && !(self.data[child] > self.data[right]) { child = right; } - let mut x = rusti::init(); - x <-> self.data[child]; + let x = replace(&mut self.data[child], rusti::init()); rusti::move_val_init(&mut self.data[pos], x); pos = child; child = 2 * pos + 1; diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index 9eab1adde4759..0c0f11fc9f023 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -17,6 +17,7 @@ destruction. They are restricted to containing `Owned` types in order to prevent use core::libc::{c_void, size_t, malloc, free}; use core::unstable::intrinsics; +use core::util; struct RcBox { value: T, @@ -52,8 +53,7 @@ impl Drop for Rc { unsafe { (*self.ptr).count -= 1; if (*self.ptr).count == 0 { - let mut x = intrinsics::uninit(); - x <-> *self.ptr; + util::replace_ptr(self.ptr, intrinsics::uninit()); free(self.ptr as *c_void) } } @@ -67,8 +67,7 @@ impl Drop for Rc { unsafe { (*self.ptr).count -= 1; if (*self.ptr).count == 0 { - let mut x = intrinsics::init(); - x <-> *self.ptr; + util::replace_ptr(self.ptr, intrinsics::init()); free(self.ptr as *c_void) } } @@ -111,13 +110,6 @@ mod test_rc { } } -#[abi = "rust-intrinsic"] -extern "rust-intrinsic" mod rusti { - fn init() -> T; - #[cfg(not(stage0))] - fn uninit() -> T; -} - #[deriving(Eq)] enum Borrow { Mutable, @@ -179,8 +171,7 @@ impl Drop for RcMut { unsafe { (*self.ptr).count -= 1; if (*self.ptr).count == 0 { - let mut x = rusti::uninit(); - x <-> *self.ptr; + util::replace_ptr(self.ptr, intrinsics::uninit()); free(self.ptr as *c_void) } } @@ -194,8 +185,7 @@ impl Drop for RcMut { unsafe { (*self.ptr).count -= 1; if (*self.ptr).count == 0 { - let mut x = rusti::init(); - x <-> *self.ptr; + util::replace_ptr(self.ptr, intrinsics::init()); free(self.ptr as *c_void) } } diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index fdc74be133544..876eb716a3833 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -13,6 +13,7 @@ use core::cmp::{Eq, Ord}; use core::vec::len; use core::vec; +use core::util::swap; type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool; @@ -63,36 +64,36 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { #[cfg(stage0)] fn part(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le) -> uint { - arr[pivot] <-> arr[right]; + swap(&mut arr[pivot], &mut arr[right]); let mut storage_index: uint = left; let mut i: uint = left; while i < right { let a: &mut T = &mut arr[i]; let b: &mut T = &mut arr[right]; if compare_func(a, b) { - arr[i] <-> arr[storage_index]; + swap(&mut arr[i], &mut arr[storage_index]); storage_index += 1; } i += 1; } - arr[storage_index] <-> arr[right]; + swap(&mut arr[storage_index], &mut arr[right]); return storage_index; } #[cfg(not(stage0))] fn part(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le) -> uint { - arr[pivot] <-> arr[right]; + vec::swap(arr, pivot, right); let mut storage_index: uint = left; let mut i: uint = left; while i < right { if compare_func(&arr[i], &arr[right]) { - arr[i] <-> arr[storage_index]; + vec::swap(arr, i, storage_index); storage_index += 1; } i += 1; } - arr[storage_index] <-> arr[right]; + vec::swap(arr, storage_index, right); return storage_index; } @@ -136,29 +137,29 @@ fn qsort3(arr: &mut [T], left: int, right: int) { j -= 1; } if i >= j { break; } - arr[i] <-> arr[j]; + vec::swap(arr, i as uint, j as uint); if arr[i] == v { p += 1; - arr[p] <-> arr[i]; + vec::swap(arr, p as uint, i as uint); } if v == arr[j] { q -= 1; - arr[j] <-> arr[q]; + vec::swap(arr, j as uint, q as uint); } } - arr[i] <-> arr[right]; + vec::swap(arr, i as uint, right as uint); j = i - 1; i += 1; let mut k: int = left; while k < p { - arr[k] <-> arr[j]; + vec::swap(arr, k as uint, j as uint); k += 1; j -= 1; if k == len::(arr) as int { break; } } k = right - 1; while k > q { - arr[i] <-> arr[k]; + vec::swap(arr, i as uint, k as uint); k -= 1; i += 1; if k == 0 { break; } @@ -273,7 +274,7 @@ fn binarysort(array: &mut [T], start: uint) { fn reverse_slice(v: &mut [T], start: uint, end:uint) { let mut i = start; while i < end / 2 { - v[i] <-> v[end - i - 1]; + vec::swap(v, i, end - i - 1); i += 1; } } @@ -493,7 +494,7 @@ impl MergeState { let mut len1 = len1; let mut len2 = len2; - array[dest] <-> array[c2]; + vec::swap(array, dest, c2); dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { @@ -502,7 +503,7 @@ impl MergeState { } if len1 == 1 { shift_vec(array, dest, c2, len2); - array[dest+len2] <-> tmp[c1]; + swap(&mut tmp[c1], &mut array[dest+len2]); return; } @@ -515,14 +516,14 @@ impl MergeState { loop { assert!(len1 > 1 && len2 != 0); if array[c2] < tmp[c1] { - array[dest] <-> array[c2]; + vec::swap(array, dest, c2); dest += 1; c2 += 1; len2 -= 1; count2 += 1; count1 = 0; if len2 == 0 { break_outer = true; } } else { - array[dest] <-> tmp[c1]; + swap(&mut array[dest], &mut tmp[c1]); dest += 1; c1 += 1; len1 -= 1; count1 += 1; count2 = 0; if len1 == 1 { @@ -548,7 +549,7 @@ impl MergeState { dest += count1; c1 += count1; len1 -= count1; if len1 <= 1 { break_outer = true; break; } } - array[dest] <-> array[c2]; + vec::swap(array, dest, c2); dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { break_outer = true; break; } @@ -561,7 +562,7 @@ impl MergeState { dest += count2; c2 += count2; len2 -= count2; if len2 == 0 { break_outer = true; break; } } - array[dest] <-> tmp[c1]; + swap(&mut array[dest], &mut tmp[c1]); dest += 1; c1 += 1; len1 -= 1; if len1 == 1 { break_outer = true; break; } min_gallop -= 1; @@ -578,7 +579,7 @@ impl MergeState { if len1 == 1 { assert!(len2 > 0); shift_vec(array, dest, c2, len2); - array[dest+len2] <-> tmp[c1]; + swap(&mut array[dest+len2], &mut tmp[c1]); } else if len1 == 0 { fail!(~"Comparison violates its contract!"); } else { @@ -603,7 +604,7 @@ impl MergeState { let mut len1 = len1; let mut len2 = len2; - array[dest] <-> array[c1]; + vec::swap(array, dest, c1); dest -= 1; c1 -= 1; len1 -= 1; if len1 == 0 { @@ -614,7 +615,7 @@ impl MergeState { dest -= len1; c1 -= len1; shift_vec(array, dest+1, c1+1, len1); - array[dest] <-> tmp[c2]; + swap(&mut array[dest], &mut tmp[c2]); return; } @@ -627,14 +628,14 @@ impl MergeState { loop { assert!(len1 != 0 && len2 > 1); if tmp[c2] < array[c1] { - array[dest] <-> array[c1]; + vec::swap(array, dest, c1); dest -= 1; c1 -= 1; len1 -= 1; count1 += 1; count2 = 0; if len1 == 0 { break_outer = true; } } else { - array[dest] <-> tmp[c2]; + swap(&mut array[dest], &mut tmp[c2]); dest -= 1; c2 -= 1; len2 -= 1; count2 += 1; count1 = 0; if len2 == 1 { @@ -663,7 +664,7 @@ impl MergeState { if len1 == 0 { break_outer = true; break; } } - array[dest] <-> tmp[c2]; + swap(&mut array[dest], &mut tmp[c2]); dest -= 1; c2 -= 1; len2 -= 1; if len2 == 1 { break_outer = true; break; } @@ -680,7 +681,7 @@ impl MergeState { copy_vec(array, dest+1, tmp.slice(c2+1, c2+1+count2)); if len2 <= 1 { break_outer = true; break; } } - array[dest] <-> array[c1]; + vec::swap(array, dest, c1); dest -= 1; c1 -= 1; len1 -= 1; if len1 == 0 { break_outer = true; break; } min_gallop -= 1; @@ -700,7 +701,7 @@ impl MergeState { dest -= len1; c1 -= len1; shift_vec(array, dest+1, c1+1, len1); - array[dest] <-> tmp[c2]; + swap(&mut array[dest], &mut tmp[c2]); } else if len2 == 0 { fail!(~"Comparison violates its contract!"); } else { @@ -1090,7 +1091,7 @@ mod big_tests { for 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); - arr[i1] <-> arr[i2]; + vec::swap(arr, i1, i2); } tim_sort(arr); // 3sort isSorted(arr); @@ -1162,7 +1163,7 @@ mod big_tests { for 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); - arr[i1] <-> arr[i2]; + vec::swap(arr, i1, i2); } tim_sort(arr); // 3sort isSorted(arr); diff --git a/src/libstd/sort_stage0.rs b/src/libstd/sort_stage0.rs index 2379e4617aae8..00bd325dd0c21 100644 --- a/src/libstd/sort_stage0.rs +++ b/src/libstd/sort_stage0.rs @@ -13,6 +13,7 @@ use core::cmp::{Eq, Ord}; use core::vec::len; use core::vec; +use core::util; type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool; @@ -63,36 +64,36 @@ pub fn merge_sort(v: &const [T], le: Le) -> ~[T] { #[cfg(stage0)] fn part(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le) -> uint { - arr[pivot] <-> arr[right]; + vec::swap(arr, pivot, right); let mut storage_index: uint = left; let mut i: uint = left; while i < right { let a: &mut T = &mut arr[i]; let b: &mut T = &mut arr[right]; if compare_func(a, b) { - arr[i] <-> arr[storage_index]; + vec::swap(arr, i, storage_index); storage_index += 1; } i += 1; } - arr[storage_index] <-> arr[right]; + vec::swap(arr, storage_index, right); return storage_index; } #[cfg(not(stage0))] fn part(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le) -> uint { - arr[pivot] <-> arr[right]; + vec::swap(arr, pivot, right); let mut storage_index: uint = left; let mut i: uint = left; while i < right { if compare_func(&arr[i], &arr[right]) { - arr[i] <-> arr[storage_index]; + vec::swap(arr, i, storage_index); storage_index += 1; } i += 1; } - arr[storage_index] <-> arr[right]; + vec::swap(arr, storage_index, right); return storage_index; } @@ -136,29 +137,29 @@ fn qsort3(arr: &mut [T], left: int, right: int) { j -= 1; } if i >= j { break; } - arr[i] <-> arr[j]; + vec::swap(arr, i as uint, j as uint); if arr[i] == v { p += 1; - arr[p] <-> arr[i]; + vec::swap(arr, p as uint, i as uint); } if v == arr[j] { q -= 1; - arr[j] <-> arr[q]; + vec::swap(arr, j as uint, q as uint); } } - arr[i] <-> arr[right]; + vec::swap(arr, i as uint, right as uint); j = i - 1; i += 1; let mut k: int = left; while k < p { - arr[k] <-> arr[j]; + vec::swap(arr, k as uint, j as uint); k += 1; j -= 1; if k == len::(arr) as int { break; } } k = right - 1; while k > q { - arr[i] <-> arr[k]; + vec::swap(arr, i as uint, k as uint); k -= 1; i += 1; if k == 0 { break; } @@ -273,7 +274,7 @@ fn binarysort(array: &mut [T], start: uint) { fn reverse_slice(v: &mut [T], start: uint, end:uint) { let mut i = start; while i < end / 2 { - v[i] <-> v[end - i - 1]; + vec::swap(v, i, end - i - 1); i += 1; } } @@ -493,7 +494,7 @@ impl MergeState { let mut len1 = len1; let mut len2 = len2; - array[dest] <-> array[c2]; + vec::swap(array, dest, c2); dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { @@ -502,7 +503,7 @@ impl MergeState { } if len1 == 1 { copy_vec(array, dest, array, c2, len2); - array[dest+len2] <-> tmp[c1]; + util::swap(&mut array[dest+len2], &mut tmp[c1]); return; } @@ -515,14 +516,14 @@ impl MergeState { loop { assert!(len1 > 1 && len2 != 0); if array[c2] < tmp[c1] { - array[dest] <-> array[c2]; + vec::swap(array, dest, c2); dest += 1; c2 += 1; len2 -= 1; count2 += 1; count1 = 0; if len2 == 0 { break_outer = true; } } else { - array[dest] <-> tmp[c1]; + util::swap(&mut array[dest], &mut tmp[c1]); dest += 1; c1 += 1; len1 -= 1; count1 += 1; count2 = 0; if len1 == 1 { @@ -546,7 +547,7 @@ impl MergeState { dest += count1; c1 += count1; len1 -= count1; if len1 <= 1 { break_outer = true; break; } } - array[dest] <-> array[c2]; + vec::swap(array, dest, c2); dest += 1; c2 += 1; len2 -= 1; if len2 == 0 { break_outer = true; break; } @@ -557,7 +558,7 @@ impl MergeState { dest += count2; c2 += count2; len2 -= count2; if len2 == 0 { break_outer = true; break; } } - array[dest] <-> tmp[c1]; + util::swap(&mut array[dest], &mut tmp[c1]); dest += 1; c1 += 1; len1 -= 1; if len1 == 1 { break_outer = true; break; } min_gallop -= 1; @@ -574,7 +575,7 @@ impl MergeState { if len1 == 1 { assert!(len2 > 0); copy_vec(array, dest, array, c2, len2); - array[dest+len2] <-> tmp[c1]; + util::swap(&mut array[dest+len2], &mut tmp[c1]); } else if len1 == 0 { fail!(~"Comparison violates its contract!"); } else { @@ -599,7 +600,7 @@ impl MergeState { let mut len1 = len1; let mut len2 = len2; - array[dest] <-> array[c1]; + vec::swap(array, dest, c1); dest -= 1; c1 -= 1; len1 -= 1; if len1 == 0 { @@ -610,7 +611,7 @@ impl MergeState { dest -= len1; c1 -= len1; copy_vec(array, dest+1, array, c1+1, len1); - array[dest] <-> tmp[c2]; + util::swap(&mut array[dest], &mut tmp[c2]); return; } @@ -623,14 +624,14 @@ impl MergeState { loop { assert!(len1 != 0 && len2 > 1); if tmp[c2] < array[c1] { - array[dest] <-> array[c1]; + vec::swap(array, dest, c1); dest -= 1; c1 -= 1; len1 -= 1; count1 += 1; count2 = 0; if len1 == 0 { break_outer = true; } } else { - array[dest] <-> tmp[c2]; + util::swap(&mut array[dest], &mut tmp[c2]); dest -= 1; c2 -= 1; len2 -= 1; count2 += 1; count1 = 0; if len2 == 1 { @@ -659,7 +660,7 @@ impl MergeState { if len1 == 0 { break_outer = true; break; } } - array[dest] <-> tmp[c2]; + util::swap(&mut array[dest], &mut tmp[c2]); dest -= 1; c2 -= 1; len2 -= 1; if len2 == 1 { break_outer = true; break; } @@ -676,7 +677,7 @@ impl MergeState { copy_vec(array, dest+1, tmp, c2+1, count2); if len2 <= 1 { break_outer = true; break; } } - array[dest] <-> array[c1]; + vec::swap(array, dest, c1); dest -= 1; c1 -= 1; len1 -= 1; if len1 == 0 { break_outer = true; break; } min_gallop -= 1; @@ -696,7 +697,7 @@ impl MergeState { dest -= len1; c1 -= len1; copy_vec(array, dest+1, array, c1+1, len1); - array[dest] <-> tmp[c2]; + util::swap(&mut array[dest], &mut tmp[c2]); } else if len2 == 0 { fail!(~"Comparison violates its contract!"); } else { @@ -1081,7 +1082,7 @@ mod big_tests { for 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); - arr[i1] <-> arr[i2]; + vec::swap(arr, i1, i2); } tim_sort(arr); // 3sort isSorted(arr); @@ -1153,7 +1154,7 @@ mod big_tests { for 3.times { let i1 = rng.gen_uint_range(0, n); let i2 = rng.gen_uint_range(0, n); - arr[i1] <-> arr[i2]; + vec::swap(arr, i1, i2); } tim_sort(arr); // 3sort isSorted(arr); diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 252bb1a6af8e9..2b39458d32dcb 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -13,7 +13,7 @@ //! `TotalOrd`. use core::iterator::*; -use core::util::replace; +use core::util::{swap, replace}; // This is implemented as an AA tree, which is a simplified variation of // a red-black tree where where red (horizontal) nodes can only be added @@ -756,8 +756,8 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, fn skew(node: &mut ~TreeNode) { if node.left.map_default(false, |x| x.level == node.level) { let mut save = node.left.swap_unwrap(); - node.left <-> save.right; // save.right now None - *node <-> save; + swap(&mut node.left, &mut save.right); // save.right now None + swap(node, &mut save); node.right = Some(save); } } @@ -768,9 +768,9 @@ fn split(node: &mut ~TreeNode) { if node.right.map_default(false, |x| x.right.map_default(false, |y| y.level == node.level)) { let mut save = node.right.swap_unwrap(); - node.right <-> save.left; // save.left now None + swap(&mut node.right, &mut save.left); // save.left now None save.level += 1; - *node <-> save; + swap(node, &mut save); node.left = Some(save); } } @@ -823,14 +823,14 @@ fn insert(node: &mut Option<~TreeNode>, fn remove(node: &mut Option<~TreeNode>, key: &K) -> Option { fn heir_swap(node: &mut ~TreeNode, - child: &mut Option<~TreeNode>) { + child: &mut Option<~TreeNode>) { // *could* be done without recursion, but it won't borrow check for child.each_mut |x| { if x.right.is_some() { heir_swap(node, &mut x.right); } else { - node.key <-> x.key; - node.value <-> x.value; + swap(&mut node.key, &mut x.key); + swap(&mut node.value, &mut x.value); } } } @@ -850,8 +850,8 @@ fn remove(node: &mut Option<~TreeNode>, if left.right.is_some() { heir_swap(save, &mut left.right); } else { - save.key <-> left.key; - save.value <-> left.value; + swap(&mut save.key, &mut left.key); + swap(&mut save.value, &mut left.value); } save.left = Some(left); (remove(&mut save.left, key), true) diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index 9b0a6cb6226c1..a9e4ec50c7c09 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -22,6 +22,7 @@ use core::io; use core::pipes::recv; use core::run; use core::to_bytes; +use core::util::replace; /** * @@ -352,9 +353,7 @@ impl TPrep for Prep { _ => { let (port, chan) = oneshot(); - let mut blk = None; - blk <-> bo; - let blk = blk.unwrap(); + let blk = replace(&mut bo, None).unwrap(); let chan = Cell(chan); do task::spawn { @@ -386,9 +385,7 @@ fn unwrap>( // FIXME(#5121) w: Work) -> T { let mut ww = w; - let mut s = None; - - ww.res <-> s; + let s = replace(&mut ww.res, None); match s { None => fail!(), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f4e3e6832292a..8aa59fd177559 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -569,7 +569,6 @@ pub enum expr_ { expr_copy(@expr), expr_assign(@expr, @expr), - expr_swap(@expr, @expr), expr_assign_op(binop, @expr, @expr), expr_field(@expr, ident, ~[@Ty]), expr_index(@expr, @expr), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d181dd87e38d1..338b9b29f004a 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -511,9 +511,6 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { expr_assign(el, er) => { expr_assign(fld.fold_expr(el), fld.fold_expr(er)) } - expr_swap(el, er) => { - expr_swap(fld.fold_expr(el), fld.fold_expr(er)) - } expr_assign_op(op, el, er) => { expr_assign_op(op, fld.fold_expr(el), fld.fold_expr(er)) } diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index a4ac038cf466f..e9e5bdfe13da5 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -40,6 +40,7 @@ pub enum ObsoleteSyntax { ObsoleteModeInFnType, ObsoleteMoveInit, ObsoleteBinaryMove, + ObsoleteSwap, ObsoleteUnsafeBlock, ObsoleteUnenforcedBound, ObsoleteImplSyntax, @@ -129,6 +130,10 @@ pub impl Parser { "binary move", "Write `foo = move bar` instead" ), + ObsoleteSwap => ( + "swap", + "Use core::util::{swap, replace} instead" + ), ObsoleteUnsafeBlock => ( "non-standalone unsafe block", "use an inner `unsafe { ... }` block instead" diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3ddc7a8792494..5aa45ab3c9bec 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -26,7 +26,7 @@ use ast::{expr_break, expr_call, expr_cast, expr_copy, expr_do_body}; use ast::{expr_field, expr_fn_block, expr_if, expr_index}; use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac}; use ast::{expr_method_call, expr_paren, expr_path, expr_repeat}; -use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary}; +use ast::{expr_ret, expr_struct, expr_tup, expr_unary}; use ast::{expr_vec, expr_vstore, expr_vstore_mut_box}; use ast::{expr_vstore_slice, expr_vstore_box}; use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl}; @@ -70,7 +70,7 @@ use parse::lexer::reader; use parse::lexer::TokenAndSpan; use parse::obsolete::{ObsoleteClassTraits}; use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator}; -use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove}; +use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove, ObsoleteSwap}; use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds}; use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; @@ -1849,9 +1849,11 @@ pub impl Parser { expr_break(None)) } token::DARROW => { + self.obsolete(*self.span, ObsoleteSwap); self.bump(); - let rhs = self.parse_expr(); - self.mk_expr(lo, rhs.span.hi, expr_swap(lhs, rhs)) + // Ignore what we get, this is an error anyway + self.parse_expr(); + self.mk_expr(lo, self.span.hi, expr_break(None)) } _ => { lhs diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 81652f9c1a100..9d2927eb74f48 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1328,12 +1328,6 @@ pub fn print_expr(s: @ps, expr: @ast::expr) { word_space(s, ~"="); print_expr(s, rhs); } - ast::expr_swap(lhs, rhs) => { - print_expr(s, lhs); - space(s.s); - word_space(s, ~"<->"); - print_expr(s, rhs); - } ast::expr_assign_op(op, lhs, rhs) => { print_expr(s, lhs); space(s.s); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 90dd49d684843..dcc94c92a886d 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -516,10 +516,6 @@ pub fn visit_expr(ex: @expr, e: E, v: vt) { (v.visit_expr)(a, e, v); } expr_copy(a) => (v.visit_expr)(a, e, v), - expr_swap(a, b) => { - (v.visit_expr)(a, e, v); - (v.visit_expr)(b, e, v); - } expr_assign_op(_, a, b) => { (v.visit_expr)(b, e, v); (v.visit_expr)(a, e, v); diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index 95a83af93d541..e6b3b3bbe20d3 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -14,6 +14,7 @@ extern mod std; use std::time::precise_time_s; use core::rand::RngUtil; +use core::util; macro_rules! bench ( ($id:ident) => (maybe_run_test(argv, stringify!($id).to_owned(), $id)) @@ -115,7 +116,7 @@ fn vec_push_all() { v.push_all(rv); } else { - v <-> rv; + util::swap(&mut v, &mut rv); v.push_all(rv); } } diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs index aef5c18499ac3..f698b2c3c1137 100644 --- a/src/test/bench/msgsend-ring-pipes.rs +++ b/src/test/bench/msgsend-ring-pipes.rs @@ -20,6 +20,7 @@ extern mod std; use core::cell::Cell; use core::pipes::recv; +use core::util; use std::time; use std::future; @@ -42,10 +43,8 @@ fn thread_ring(i: uint, // Send/Receive lots of messages. for uint::range(0, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = None; - let mut num_port2 = None; - num_chan2 <-> num_chan; - num_port2 <-> num_port; + let num_chan2 = util::replace(&mut num_chan, None); + let num_port2 = util::replace(&mut num_port, None); num_chan = Some(ring::client::num(num_chan2.unwrap(), i * j)); let port = num_port2.unwrap(); match recv(port) { diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index d1f3dbf22ce83..210bf5cb6de41 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -17,6 +17,7 @@ use core::hashmap::HashMap; use core::io::ReaderUtil; use core::comm::{stream, Port, Chan}; use core::cmp::Ord; +use core::util; // given a map, print a sorted version of it fn sort_and_fmt(mm: &HashMap<~[u8], uint>, total: uint) -> ~str { @@ -159,8 +160,7 @@ fn main() { let mut from_child = ~[]; let to_child = vec::mapi(sizes, |ii, sz| { let sz = *sz; - let mut stream = None; - stream <-> streams[ii]; + let stream = util::replace(&mut streams[ii], None); let (from_child_, to_parent_) = stream.unwrap(); from_child.push(from_child_); diff --git a/src/test/compile-fail/liveness-assign-imm-local-in-swap.rs b/src/test/compile-fail/liveness-assign-imm-local-in-swap.rs deleted file mode 100644 index 40ccfca919b67..0000000000000 --- a/src/test/compile-fail/liveness-assign-imm-local-in-swap.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn test1() { - let v: int; - let mut w: int; - v = 1; //~ NOTE prior assignment occurs here - w = 2; - v <-> w; //~ ERROR re-assignment of immutable variable -} - -fn test2() { - let v: int; - let mut w: int; - v = 1; //~ NOTE prior assignment occurs here - w = 2; - w <-> v; //~ ERROR re-assignment of immutable variable -} - -fn main() { -} diff --git a/src/test/compile-fail/liveness-swap-uninit.rs b/src/test/compile-fail/liveness-swap-uninit.rs deleted file mode 100644 index b2d475dd78926..0000000000000 --- a/src/test/compile-fail/liveness-swap-uninit.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - let mut x = 3; - let y; - x <-> y; //~ ERROR use of possibly uninitialized variable: `y` - copy x; -} diff --git a/src/test/compile-fail/moves-based-on-type-exprs.rs b/src/test/compile-fail/moves-based-on-type-exprs.rs index 7356c227360c8..5b733129ee5dc 100644 --- a/src/test/compile-fail/moves-based-on-type-exprs.rs +++ b/src/test/compile-fail/moves-based-on-type-exprs.rs @@ -87,7 +87,7 @@ fn f110() { fn f120() { let x = ~[~"hi", ~"ho"]; - x[0] <-> x[1]; + vec::swap(x, 0, 1); touch(&x[0]); touch(&x[1]); } diff --git a/src/test/compile-fail/swap-no-lval.rs b/src/test/compile-fail/swap-no-lval.rs deleted file mode 100644 index eca5fb0d315d8..0000000000000 --- a/src/test/compile-fail/swap-no-lval.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -fn main() { - 5 <-> 3; - //~^ ERROR cannot assign - //~^^ ERROR cannot assign -} diff --git a/src/test/run-pass/borrowck-mut-uniq.rs b/src/test/run-pass/borrowck-mut-uniq.rs index 778637701c5fd..023eaae0a7648 100644 --- a/src/test/run-pass/borrowck-mut-uniq.rs +++ b/src/test/run-pass/borrowck-mut-uniq.rs @@ -8,14 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::util; + struct Ints {sum: ~int, values: ~[int]} fn add_int(x: &mut Ints, v: int) { *x.sum += v; let mut values = ~[]; - x.values <-> values; + util::swap(&mut values, &mut x.values); values.push(v); - x.values <-> values; + util::swap(&mut values, &mut x.values); } fn iter_ints(x: &Ints, f: &fn(x: &int) -> bool) -> bool { diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index acd26a88a7361..60daaea57d758 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -10,8 +10,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::util; + // tjc: I don't know why pub mod pipes { + use core::util; use core::cast::{forget, transmute}; pub struct Stuff { @@ -104,8 +107,7 @@ pub mod pipes { match old_state { empty | blocked => { task::yield(); } full => { - let mut payload = None; - payload <-> (*p).payload; + let payload = util::replace(&mut p.payload, None); return Some(payload.unwrap()) } terminated => { @@ -159,10 +161,9 @@ pub mod pipes { fn finalize(&self) { unsafe { if self.p != None { - let mut p = None; let self_p: &mut Option<*packet> = cast::transmute(&self.p); - p <-> *self_p; + let p = util::replace(self_p, None); sender_terminate(p.unwrap()) } } @@ -171,9 +172,7 @@ pub mod pipes { pub impl send_packet { fn unwrap(&mut self) -> *packet { - let mut p = None; - p <-> self.p; - p.unwrap() + util::replace(&mut self.p, None).unwrap() } } @@ -192,10 +191,9 @@ pub mod pipes { fn finalize(&self) { unsafe { if self.p != None { - let mut p = None; let self_p: &mut Option<*packet> = cast::transmute(&self.p); - p <-> *self_p; + let p = util::replace(self_p, None); receiver_terminate(p.unwrap()) } } @@ -204,9 +202,7 @@ pub mod pipes { pub impl recv_packet { fn unwrap(&mut self) -> *packet { - let mut p = None; - p <-> self.p; - p.unwrap() + util::replace(&mut self.p, None).unwrap() } } @@ -225,6 +221,7 @@ pub mod pipes { pub mod pingpong { use core::cast; use core::ptr; + use core::util; pub struct ping(::pipes::send_packet); pub struct pong(::pipes::send_packet); diff --git a/src/test/run-pass/regions-infer-borrow-scope-addr-of.rs b/src/test/run-pass/regions-infer-borrow-scope-addr-of.rs index 39da08de6df2c..a87a899cafeaf 100644 --- a/src/test/run-pass/regions-infer-borrow-scope-addr-of.rs +++ b/src/test/run-pass/regions-infer-borrow-scope-addr-of.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::util; + pub fn main() { let mut x = 4; @@ -24,6 +26,6 @@ pub fn main() { } } let mut y = 4; - y <-> x; + util::swap(&mut y, &mut x); } } diff --git a/src/test/run-pass/swap-1.rs b/src/test/run-pass/swap-1.rs index feb7a88dc3480..ed69fa41d711f 100644 --- a/src/test/run-pass/swap-1.rs +++ b/src/test/run-pass/swap-1.rs @@ -8,7 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::util; + pub fn main() { let mut x = 3; let mut y = 7; - x <-> y; assert!((x == 7)); assert!((y == 3)); + util::swap(&mut x, &mut y); + assert!((x == 7)); assert!((y == 3)); } diff --git a/src/test/run-pass/swap-2.rs b/src/test/run-pass/swap-2.rs index 24794b0359168..63b377b26d83e 100644 --- a/src/test/run-pass/swap-2.rs +++ b/src/test/run-pass/swap-2.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -fn swap(v: &mut [T], i: int, j: int) { v[i] <-> v[j]; } +use core::util; pub fn main() { let mut a: ~[int] = ~[0, 1, 2, 3, 4, 5, 6]; - swap(a, 2, 4); + vec::swap(a, 2, 4); assert!((a[2] == 4)); assert!((a[4] == 2)); let mut n = 42; - n <-> a[0]; + util::swap(&mut n, &mut a[0]); assert!((a[0] == 42)); assert!((n == 0)); } diff --git a/src/test/run-pass/swap-overlapping.rs b/src/test/run-pass/swap-overlapping.rs index 90b2ceef71a76..05f943bf928ca 100644 --- a/src/test/run-pass/swap-overlapping.rs +++ b/src/test/run-pass/swap-overlapping.rs @@ -10,6 +10,8 @@ // Issue #5041 - avoid overlapping memcpy when src and dest of a swap are the same +use core::util; + pub fn main() { let mut test = TestDescAndFn { desc: TestDesc { @@ -22,7 +24,10 @@ pub fn main() { } fn do_swap(test: &mut TestDescAndFn) { - *test <-> *test; + unsafe { + util::swap_ptr(ptr::to_mut_unsafe_ptr(test), + ptr::to_mut_unsafe_ptr(test)); + } } pub enum TestName { diff --git a/src/test/run-pass/unique-swap.rs b/src/test/run-pass/unique-swap.rs index 6cd7b358c55e7..bf58e2c7cb53b 100644 --- a/src/test/run-pass/unique-swap.rs +++ b/src/test/run-pass/unique-swap.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::util; + pub fn main() { let mut i = ~100; let mut j = ~200; - i <-> j; + util::swap(&mut i, &mut j); assert!(i == ~200); assert!(j == ~100); } diff --git a/src/test/run-pass/weird-exprs.rs b/src/test/run-pass/weird-exprs.rs index ed0032b93eafe..38aa56b65125b 100644 --- a/src/test/run-pass/weird-exprs.rs +++ b/src/test/run-pass/weird-exprs.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::util; + // Just a grab bag of stuff that you wouldn't want to actually write. fn strange() -> bool { let _x: bool = return true; } @@ -52,7 +54,7 @@ fn notsure() { let mut _y = (_x = 0) == (_x = 0); let mut _z = (_x = 0) < (_x = 0); let _a = (_x += 0) == (_x = 0); - let _b = (_y <-> _z) == (_y <-> _z); + let _b = util::swap(&mut _y, &mut _z) == util::swap(&mut _y, &mut _z); } fn canttouchthis() -> uint {