about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-05-10 20:35:00 -0700
committerbors <bors@rust-lang.org>2013-05-10 20:35:00 -0700
commit9f106a643e6cdf2f3c8d62bcec61da087ed24c5b (patch)
treeb5593b086685c556b08f9772daff3e1391b1356f /src/libcore
parentc49cf8b3300a97201058debd63b0f7aef34d3c35 (diff)
parent60803e5fc81ed7065c91c0b1725dbbd4da0af3f7 (diff)
downloadrust-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).
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/cell.rs5
-rw-r--r--src/libcore/comm.rs29
-rw-r--r--src/libcore/hashmap.rs24
-rw-r--r--src/libcore/pipes.rs29
-rw-r--r--src/libcore/util.rs74
-rw-r--r--src/libcore/vec.rs81
6 files changed, 138 insertions, 104 deletions
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());
         }