diff options
| author | bors <bors@rust-lang.org> | 2013-05-10 20:35:00 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-05-10 20:35:00 -0700 |
| commit | 9f106a643e6cdf2f3c8d62bcec61da087ed24c5b (patch) | |
| tree | b5593b086685c556b08f9772daff3e1391b1356f | |
| parent | c49cf8b3300a97201058debd63b0f7aef34d3c35 (diff) | |
| parent | 60803e5fc81ed7065c91c0b1725dbbd4da0af3f7 (diff) | |
| download | rust-9f106a643e6cdf2f3c8d62bcec61da087ed24c5b.tar.gz rust-9f106a643e6cdf2f3c8d62bcec61da087ed24c5b.zip | |
auto merge of #6260 : alexcrichton/rust/issue-3466-no-swap, r=pcwalton
There may be a more efficient implementation of `core::util::swap_ptr`. The issue mentioned using `move_val_init`, but I couldn't figure out what that did, so I just used `copy_memory` a few times instead. I'm not exactly the best at reading LLVM generated by rust, but this does appear to be optimized away just as expected (when possible).
48 files changed, 296 insertions, 430 deletions
diff --git a/doc/rust.md b/doc/rust.md index ac7125be424..60848441e4e 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 2a3d8dc1481..d8367fbdc2d 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<T> { @@ -184,7 +185,8 @@ impl<T: Owned> Drop for Unique<T> { 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 c7f9e377571..18e75fb1aa9 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<T> Cell<T> { 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 7eaa8535493..140eb41fdf3 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<T: Owned> GenericChan<T> for Chan<T> { #[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<T: Owned> GenericSmartChan<T> for Chan<T> { #[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<T: Owned> GenericPort<T> for Port<T> { #[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<T: Owned> GenericPort<T> for Port<T> { #[inline(always)] fn try_recv(&self) -> Option<T> { 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<T: Owned> Peekable<T> for Port<T> { #[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<T:Owned> GenericPort<T> for PortSet<T> { 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<T:Owned> GenericPort<T> for PortSet<T> { } } } - ports <-> *self_ports; + *self_ports = ports; result } } @@ -320,8 +315,7 @@ impl<T: Owned> GenericChan<T> for SharedChan<T> { 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<T: Owned> GenericSmartChan<T> for SharedChan<T> { 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 b5ae07208fc..590d4ab3bcb 100644 --- a/src/libcore/hashmap.rs +++ b/src/libcore/hashmap.rs @@ -176,16 +176,13 @@ priv impl<K:Hash + Eq,V> HashMap<K, V> { /// 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<K:Hash + Eq,V> HashMap<K, V> { }; 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<K:Hash + Eq,V> HashMap<K, V> { 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<K: Hash + Eq, V> HashMap<K, V> { } 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 8301254fbdd..fe9c78198bb 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_<T:Owned>(p: &mut Packet<T>) -> Option<T> { // 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_<T:Owned>(p: &mut Packet<T>) -> Option<T> { 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<T:Owned,Tbuffer:Owned> Drop for SendPacketBuffered<T,Tbuffer> { unsafe { let this: &mut SendPacketBuffered<T,Tbuffer> = 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<T,Tbuffer>(p: *mut Packet<T>) pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { fn unwrap(&mut self) -> *mut Packet<T> { - 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<T,Tbuffer> SendPacketBuffered<T,Tbuffer> { fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> { //error!("send reuse_buffer"); - let mut tmp = None; - tmp <-> self.buffer; - tmp.unwrap() + replace(&mut self.buffer, None).unwrap() } } @@ -738,8 +732,7 @@ impl<T:Owned,Tbuffer:Owned> Drop for RecvPacketBuffered<T,Tbuffer> { unsafe { let this: &mut RecvPacketBuffered<T,Tbuffer> = 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<T:Owned,Tbuffer:Owned> Drop for RecvPacketBuffered<T,Tbuffer> { pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> { fn unwrap(&mut self) -> *mut Packet<T> { - let mut p = None; - p <-> self.p; - p.unwrap() + replace(&mut self.p, None).unwrap() } fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> { - 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 43616ebfd30..db9a17cf97f 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<T>(_x: T) { } #[inline(always)] pub fn with<T,R>( 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<T,R>( */ #[inline(always)] pub fn swap<T>(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<T>(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<T>(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<T>(dest: &mut T, mut src: T) -> T { + swap(dest, &mut src); + src } /** @@ -57,10 +116,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) { * value, without deinitialising or copying either one. */ #[inline(always)] -pub fn replace<T>(dest: &mut T, src: T) -> T { - let mut tmp = src; - swap(dest, &mut tmp); - tmp +pub unsafe fn replace_ptr<T>(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 7eba2cbf0cc..77314b173d9 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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T>(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<T:Eq>(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<T:Eq>(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<T>(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<T, U>(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<T>(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<T>(v: &mut [T]) { let mut i: uint = 0; let ln = len::<T>(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<T>(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 27f6ae33ba3..2f116cb1b28 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 f1fa5144f4c..dc08fb39ad9 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 0bd73a15d50..52274f3d305 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 0e819c66f09..7675efa76f4 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 040ff30f9e6..2471e383bca 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 1b7cdf3ac80..ed3dfdc07c3 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 cbad7bcb3a6..3c2738d3ae8 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 737548ee868..829a1e399de 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 baa28b64982..7c79693a8b2 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 2274259f18c..55c1f03b330 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 a8cd7f5f41c..836ca1cfa45 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 4eb359e48a8..c94acaa1f70 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<T> { @@ -142,9 +144,7 @@ fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] { 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 b1b2fa2cd28..ac23ea1a6e2 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<A> Future<A> { } } { - 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<A> Future<A> { } } { - 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 bdb93142472..ded632b29d9 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 <T:Ord> PriorityQueue<T> { /// 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 <T:Ord> PriorityQueue<T> { /// 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 <T:Ord> PriorityQueue<T> { /// 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 <T:Ord> PriorityQueue<T> { 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 <T:Ord> PriorityQueue<T> { 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 <T:Ord> PriorityQueue<T> { 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 <T:Ord> PriorityQueue<T> { 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 <T:Ord> PriorityQueue<T> { 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 9eab1adde47..0c0f11fc9f0 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<T> { value: T, @@ -52,8 +53,7 @@ impl<T: Owned> Drop for Rc<T> { 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<T: Owned> Drop for Rc<T> { 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>() -> T; - #[cfg(not(stage0))] - fn uninit<T>() -> T; -} - #[deriving(Eq)] enum Borrow { Mutable, @@ -179,8 +171,7 @@ impl<T: Owned> Drop for RcMut<T> { 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<T: Owned> Drop for RcMut<T> { 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 fdc74be1335..876eb716a38 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<T:Copy>(v: &[T], le: Le<T>) -> ~[T] { #[cfg(stage0)] fn part<T>(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le<T>) -> 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<T>(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le<T>) -> 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<T:Copy + Ord + Eq>(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::<T>(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<T:Copy + Ord>(array: &mut [T], start: uint) { fn reverse_slice<T>(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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { } 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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 2379e4617aa..00bd325dd0c 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<T:Copy>(v: &const [T], le: Le<T>) -> ~[T] { #[cfg(stage0)] fn part<T>(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le<T>) -> 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<T>(arr: &mut [T], left: uint, right: uint, pivot: uint, compare_func: Le<T>) -> 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<T:Copy + Ord + Eq>(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::<T>(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<T:Copy + Ord>(array: &mut [T], start: uint) { fn reverse_slice<T>(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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { } 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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<T:Copy + Ord> MergeState<T> { 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 252bb1a6af8..2b39458d32d 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<K, V>>, fn skew<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) { 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<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>) { 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<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>, fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> Option<V> { fn heir_swap<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>, - child: &mut Option<~TreeNode<K, V>>) { + child: &mut Option<~TreeNode<K, V>>) { // *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<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>, 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 9b0a6cb6226..a9e4ec50c7c 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<T:Owned + Decodable<json::Decoder>>( // FIXME(#5121) w: Work<T>) -> 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 f4e3e683229..8aa59fd1775 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 d181dd87e38..338b9b29f00 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 a4ac038cf46..e9e5bdfe13d 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 3ddc7a87924..5aa45ab3c9b 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 81652f9c1a1..9d2927eb74f 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 90dd49d6848..dcc94c92a88 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -516,10 +516,6 @@ pub fn visit_expr<E: Copy>(ex: @expr, e: E, v: vt<E>) { (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 95a83af93d5..e6b3b3bbe20 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 aef5c18499a..f698b2c3c11 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 d1f3dbf22ce..210bf5cb6de 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 40ccfca919b..00000000000 --- 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 b2d475dd789..00000000000 --- 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 7356c227360..5b733129ee5 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 eca5fb0d315..00000000000 --- 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 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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 778637701c5..023eaae0a76 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 acd26a88a73..60daaea57d7 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<T> { @@ -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<T>> = 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<T:Owned> send_packet<T> { fn unwrap(&mut self) -> *packet<T> { - 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<T>> = 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<T:Owned> recv_packet<T> { fn unwrap(&mut self) -> *packet<T> { - 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<pong>); pub struct pong(::pipes::send_packet<ping>); 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 39da08de6df..a87a899cafe 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 feb7a88dc34..ed69fa41d71 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 24794b03591..63b377b26d8 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<T>(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 90b2ceef71a..05f943bf928 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 6cd7b358c55..bf58e2c7cb5 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 ed0032b93ea..38aa56b6512 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 { |
