about summary refs log tree commit diff
path: root/src/libstd
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/libstd
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/libstd')
-rw-r--r--src/libstd/deque.rs6
-rw-r--r--src/libstd/future.rs7
-rw-r--r--src/libstd/priority_queue.rs24
-rw-r--r--src/libstd/rc.rs20
-rw-r--r--src/libstd/sort.rs59
-rw-r--r--src/libstd/sort_stage0.rs59
-rw-r--r--src/libstd/treemap.rs20
-rw-r--r--src/libstd/workcache.rs9
8 files changed, 96 insertions, 108 deletions
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!(),