about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-02-12 20:40:19 -0800
committerbors <bors@rust-lang.org>2013-02-12 20:40:19 -0800
commit27b3e01377ff9b25a38a76937c3d14cd9d0fb2b0 (patch)
treed2f3367752c8410f35d30671b8dc175eb55db3c4 /src/libstd
parent1a394e57f7a622e67c13eae8bc26848eea31334a (diff)
parentab2534974caf39e69b401442ff1a9077b94c46c1 (diff)
downloadrust-27b3e01377ff9b25a38a76937c3d14cd9d0fb2b0.tar.gz
rust-27b3e01377ff9b25a38a76937c3d14cd9d0fb2b0.zip
auto merge of #4914 : nikomatsakis/rust/issue-4856, r=nikomatsakis
and then adjust code to match. rs=unsound (will review post-landing)

rs=unsound
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/arc.rs85
-rw-r--r--src/libstd/priority_queue.rs6
-rw-r--r--src/libstd/smallintmap.rs9
-rw-r--r--src/libstd/treemap.rs56
4 files changed, 87 insertions, 69 deletions
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs
index a1fd7a66f7e..ff28d2cbebf 100644
--- a/src/libstd/arc.rs
+++ b/src/libstd/arc.rs
@@ -184,25 +184,30 @@ impl<T: Owned> &MutexARC<T> {
      */
     #[inline(always)]
     unsafe fn access<U>(blk: fn(x: &mut T) -> U) -> U {
-        let state = unsafe { get_shared_mutable_state(&self.x) };
-        // Borrowck would complain about this if the function were not already
-        // unsafe. See borrow_rwlock, far below.
-        do (&state.lock).lock {
-            check_poison(true, state.failed);
-            let _z = PoisonOnFail(&mut state.failed);
-            blk(&mut state.data)
+        unsafe {
+            let state = get_shared_mutable_state(&self.x);
+            // Borrowck would complain about this if the function were
+            // not already unsafe. See borrow_rwlock, far below.
+            do (&(*state).lock).lock {
+                check_poison(true, (*state).failed);
+                let _z = PoisonOnFail(&mut (*state).failed);
+                blk(&mut (*state).data)
+            }
         }
     }
     /// As access(), but with a condvar, as sync::mutex.lock_cond().
     #[inline(always)]
     unsafe fn access_cond<U>(blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U {
-        let state = unsafe { get_shared_mutable_state(&self.x) };
-        do (&state.lock).lock_cond |cond| {
-            check_poison(true, state.failed);
-            let _z = PoisonOnFail(&mut state.failed);
-            blk(&mut state.data,
-                &Condvar { is_mutex: true, failed: &mut state.failed,
-                           cond: cond })
+        unsafe {
+            let state = get_shared_mutable_state(&self.x);
+            do (&(*state).lock).lock_cond |cond| {
+                check_poison(true, (*state).failed);
+                let _z = PoisonOnFail(&mut (*state).failed);
+                blk(&mut (*state).data,
+                    &Condvar {is_mutex: true,
+                              failed: &mut (*state).failed,
+                              cond: cond })
+            }
         }
     }
 }
@@ -285,8 +290,10 @@ pub fn RWARC<T: Const Owned>(user_data: T) -> RWARC<T> {
  * Create a reader/writer ARC with the supplied data and a specified number
  * of condvars (as sync::rwlock_with_condvars).
  */
-pub fn rw_arc_with_condvars<T: Const Owned>(user_data: T,
-                                       num_condvars: uint) -> RWARC<T> {
+pub fn rw_arc_with_condvars<T: Const Owned>(
+    user_data: T,
+    num_condvars: uint) -> RWARC<T>
+{
     let data =
         RWARCInner { lock: rwlock_with_condvars(num_condvars),
                      failed: false, data: move user_data };
@@ -315,23 +322,28 @@ impl<T: Const Owned> &RWARC<T> {
      */
     #[inline(always)]
     fn write<U>(blk: fn(x: &mut T) -> U) -> U {
-        let state = unsafe { get_shared_mutable_state(&self.x) };
-        do borrow_rwlock(state).write {
-            check_poison(false, state.failed);
-            let _z = PoisonOnFail(&mut state.failed);
-            blk(&mut state.data)
+        unsafe {
+            let state = get_shared_mutable_state(&self.x);
+            do (*borrow_rwlock(state)).write {
+                check_poison(false, (*state).failed);
+                let _z = PoisonOnFail(&mut (*state).failed);
+                blk(&mut (*state).data)
+            }
         }
     }
     /// As write(), but with a condvar, as sync::rwlock.write_cond().
     #[inline(always)]
     fn write_cond<U>(blk: fn(x: &x/mut T, c: &c/Condvar) -> U) -> U {
-        let state = unsafe { get_shared_mutable_state(&self.x) };
-        do borrow_rwlock(state).write_cond |cond| {
-            check_poison(false, state.failed);
-            let _z = PoisonOnFail(&mut state.failed);
-            blk(&mut state.data,
-                &Condvar { is_mutex: false, failed: &mut state.failed,
-                           cond: cond })
+        unsafe {
+            let state = get_shared_mutable_state(&self.x);
+            do (*borrow_rwlock(state)).write_cond |cond| {
+                check_poison(false, (*state).failed);
+                let _z = PoisonOnFail(&mut (*state).failed);
+                blk(&mut (*state).data,
+                    &Condvar {is_mutex: false,
+                              failed: &mut (*state).failed,
+                              cond: cond})
+            }
         }
     }
     /**
@@ -369,11 +381,14 @@ impl<T: Const Owned> &RWARC<T> {
      * ~~~
      */
     fn write_downgrade<U>(blk: fn(v: RWWriteMode<T>) -> U) -> U {
-        let state = unsafe { get_shared_mutable_state(&self.x) };
-        do borrow_rwlock(state).write_downgrade |write_mode| {
-            check_poison(false, state.failed);
-            blk(RWWriteMode((&mut state.data, move write_mode,
-                              PoisonOnFail(&mut state.failed))))
+        unsafe {
+            let state = get_shared_mutable_state(&self.x);
+            do (*borrow_rwlock(state)).write_downgrade |write_mode| {
+                check_poison(false, (*state).failed);
+                blk(RWWriteMode((&mut (*state).data,
+                                 move write_mode,
+                                 PoisonOnFail(&mut (*state).failed))))
+            }
         }
     }
 
@@ -417,8 +432,8 @@ pub fn unwrap_rw_arc<T: Const Owned>(arc: RWARC<T>) -> T {
 // lock it. This wraps the unsafety, with the justification that the 'lock'
 // field is never overwritten; only 'failed' and 'data'.
 #[doc(hidden)]
-fn borrow_rwlock<T: Const Owned>(state: &r/mut RWARCInner<T>) -> &r/RWlock {
-    unsafe { cast::transmute(&mut state.lock) }
+fn borrow_rwlock<T: Const Owned>(state: *const RWARCInner<T>) -> *RWlock {
+    unsafe { cast::transmute(&const (*state).lock) }
 }
 
 // FIXME (#3154) ice with struct/&<T> prevents these from being structs.
diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs
index 5248ab1742e..a64aa5e9687 100644
--- a/src/libstd/priority_queue.rs
+++ b/src/libstd/priority_queue.rs
@@ -81,7 +81,8 @@ impl <T: Ord> PriorityQueue<T> {
     /// Push an item onto the queue
     fn push(&mut self, item: T) {
         self.data.push(item);
-        self.siftup(0, self.len() - 1);
+        let new_len = self.len() - 1;
+        self.siftup(0, new_len);
     }
 
     /// Optimized version of a push followed by a pop
@@ -179,7 +180,8 @@ impl <T: Ord> PriorityQueue<T> {
     }
 
     priv fn siftdown(&mut self, pos: uint) {
-        self.siftdown_range(pos, self.len());
+        let len = self.len();
+        self.siftdown_range(pos, len);
     }
 }
 
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs
index 9642dd0c3dd..2e5cd8956cd 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -134,10 +134,11 @@ pub impl<V> SmallIntMap<V> {
 pub impl<V: Copy> SmallIntMap<V> {
     fn update_with_key(&mut self, key: uint, val: V,
                        ff: fn(uint, V, V) -> V) -> bool {
-        match self.find(&key) {
-          None => self.insert(key, val),
-          Some(orig) => self.insert(key, ff(key, copy *orig, val)),
-        }
+        let new_val = match self.find(&key) {
+            None => val,
+            Some(orig) => ff(key, *orig, val)
+        };
+        self.insert(key, new_val)
     }
 
     fn update(&mut self, key: uint, newval: V, ff: fn(V, V) -> V) -> bool {
diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs
index 26bf232adf5..2fdaeb545a2 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -673,45 +673,45 @@ fn remove<K: Ord, V>(node: &mut Option<~TreeNode<K, V>>, key: &K) -> bool {
             }
         };
 
-        if this {
-            *node = None;
-            return true;
-        }
+        if !this {
+            let left_level = save.left.map_default(0, |x| x.level);
+            let right_level = save.right.map_default(0, |x| x.level);
 
-        let left_level = save.left.map_default(0, |x| x.level);
-        let right_level = save.right.map_default(0, |x| x.level);
+            // re-balance, if necessary
+            if left_level < save.level - 1 || right_level < save.level - 1 {
+                save.level -= 1;
 
-        // re-balance, if necessary
-        if left_level < save.level - 1 || right_level < save.level - 1 {
-            save.level -= 1;
+                if right_level > save.level {
+                    do save.right.mutate |mut x| { x.level = save.level; x }
+                }
 
-            if right_level > save.level {
-                do save.right.mutate |mut x| { x.level = save.level; x }
-            }
+                skew(save);
 
-            skew(save);
+                match save.right {
+                    Some(ref mut right) => {
+                        skew(right);
+                        match right.right {
+                            Some(ref mut x) => { skew(x) },
+                            None => ()
+                        }
+                    }
+                    None => ()
+                }
 
-            match save.right {
-              Some(ref mut right) => {
-                skew(right);
-                match right.right {
-                  Some(ref mut x) => { skew(x) },
-                  None => ()
+                split(save);
+                match save.right {
+                    Some(ref mut x) => { split(x) },
+                    None => ()
                 }
-              }
-              None => ()
             }
 
-            split(save);
-            match save.right {
-              Some(ref mut x) => { split(x) },
-              None => ()
-            }
+            return removed;
         }
-
-        removed
       }
     }
+
+    *node = None;
+    return true;
 }
 
 #[cfg(test)]