diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-01-23 18:15:06 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-01-24 13:52:22 -0800 |
| commit | ad25e208ee4978ca20123bcd2f34c16504518b8d (patch) | |
| tree | 812ad433f7aaf53000f5bb257cb57c0100f518ea /src/libstd | |
| parent | bbbb80559c8e321dc023c48579367e2ef1349b4b (diff) | |
| download | rust-ad25e208ee4978ca20123bcd2f34c16504518b8d.tar.gz rust-ad25e208ee4978ca20123bcd2f34c16504518b8d.zip | |
librustc: Allow `&mut` to be loaned; allow `self` to be loaned; make `&mut` loanable to `&`. r=nmatsakis
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/arc.rs | 31 | ||||
| -rw-r--r-- | src/libstd/priority_queue.rs | 11 | ||||
| -rw-r--r-- | src/libstd/treemap.rs | 168 |
3 files changed, 136 insertions, 74 deletions
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs index 4d1a8af0b1d..536f43d648c 100644 --- a/src/libstd/arc.rs +++ b/src/libstd/arc.rs @@ -241,19 +241,24 @@ fn check_poison(is_mutex: bool, failed: bool) { #[doc(hidden)] struct PoisonOnFail { - failed: &mut bool, + failed: *mut bool, } impl PoisonOnFail : Drop { fn finalize(&self) { - /* assert !*self.failed; -- might be false in case of cond.wait() */ - if task::failing() { *self.failed = true; } + unsafe { + /* assert !*self.failed; + -- might be false in case of cond.wait() */ + if task::failing() { + *self.failed = true; + } + } } } -fn PoisonOnFail(failed: &r/mut bool) -> PoisonOnFail/&r { +fn PoisonOnFail(failed: &r/mut bool) -> PoisonOnFail { PoisonOnFail { - failed: failed + failed: ptr::to_mut_unsafe_ptr(failed) } } @@ -415,7 +420,7 @@ pub fn unwrap_rw_arc<T: Const Owned>(arc: RWARC<T>) -> T { // 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_immut(&mut state.lock) } + unsafe { cast::transmute(&mut state.lock) } } // FIXME (#3154) ice with struct/&<T> prevents these from being structs. @@ -442,12 +447,14 @@ impl<T: Const Owned> &RWWriteMode<T> { match *self { RWWriteMode((ref data, ref token, ref poison)) => { do token.write_cond |cond| { - let cvar = Condvar { - is_mutex: false, - failed: &mut *poison.failed, - cond: cond - }; - blk(&mut **data, &cvar) + unsafe { + let cvar = Condvar { + is_mutex: false, + failed: &mut *poison.failed, + cond: cond + }; + blk(&mut **data, &cvar) + } } } } diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index a348026f072..01b62797a8d 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -19,6 +19,7 @@ use core::vec; #[abi = "rust-intrinsic"] extern "C" mod rusti { fn move_val_init<T>(dst: &mut T, -src: T); + fn init<T>() -> T; } pub struct PriorityQueue <T: Ord>{ @@ -136,8 +137,9 @@ impl <T: Ord> PriorityQueue<T> { while pos > start { let parent = (pos - 1) >> 1; if new > self.data[parent] { - rusti::move_val_init(&mut self.data[pos], - move *addr_of(&self.data[parent])); + let mut x = rusti::init(); + x <-> self.data[parent]; + rusti::move_val_init(&mut self.data[pos], move x); pos = parent; loop } @@ -159,8 +161,9 @@ impl <T: Ord> PriorityQueue<T> { if right < end && !(self.data[child] > self.data[right]) { child = right; } - rusti::move_val_init(&mut self.data[pos], - move *addr_of(&self.data[child])); + let mut x = rusti::init(); + x <-> self.data[child]; + rusti::move_val_init(&mut self.data[pos], move x); pos = child; child = 2 * pos + 1; } diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 95397254171..36d919494f1 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -55,8 +55,10 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: Eq { unsafe { // unsafe as a purity workaround // ICE: x.next() != y.next() - let (x1, x2) = x.next().unwrap(); - let (y1, y2) = y.next().unwrap(); + x = x.next(); + y = y.next(); + let (x1, x2) = x.get().unwrap(); + let (y1, y2) = y.get().unwrap(); if x1 != y1 || x2 != y2 { return false @@ -160,35 +162,46 @@ impl <K: Ord, V> TreeMap<K, V> { /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). pure fn iter(&self) -> TreeMapIterator/&self<K, V> { - TreeMapIterator{stack: ~[], node: &self.root} + TreeMapIterator{stack: ~[], node: &self.root, current: None} } } /// Lazy forward iterator over a map pub struct TreeMapIterator<K: Ord, V> { priv stack: ~[&~TreeNode<K, V>], - priv node: &Option<~TreeNode<K, V>> + priv node: &Option<~TreeNode<K, V>>, + priv current: Option<&~TreeNode<K, V>> } impl <K: Ord, V> TreeMapIterator<K, V> { - /// Advance the iterator to the next node (in order) and return a - /// tuple with a reference to the key and value. If there are no - /// more nodes, return `None`. - fn next(&mut self) -> Option<(&self/K, &self/V)> { - while !self.stack.is_empty() || self.node.is_some() { - match *self.node { + // Returns the current node, or None if this iterator is at the end. + fn get(&const self) -> Option<(&self/K, &self/V)> { + match self.current { + Some(res) => Some((&res.key, &res.value)), + None => None + } + } + + /// Advance the iterator to the next node (in order). If this iterator + /// is finished, does nothing. + fn next(self) -> TreeMapIterator/&self<K, V> { + let mut this = self; + while !this.stack.is_empty() || this.node.is_some() { + match *this.node { Some(ref x) => { - self.stack.push(x); - self.node = &x.left; + this.stack.push(x); + this.node = &x.left; } None => { - let res = self.stack.pop(); - self.node = &res.right; - return Some((&res.key, &res.value)); + let res = this.stack.pop(); + this.node = &res.right; + this.current = Some(res); + return this; } } } - None + this.current = None; + return this; } } @@ -256,15 +269,19 @@ impl <T: Ord> TreeSet<T> { let mut x = self.iter(); let mut y = other.iter(); unsafe { // purity workaround - let mut a = x.next(); - let mut b = y.next(); + x = x.next(); + y = y.next(); + let mut a = x.get(); + let mut b = y.get(); while a.is_some() && b.is_some() { let a1 = a.unwrap(); let b1 = b.unwrap(); if a1 < b1 { - a = x.next(); + x = x.next(); + a = x.get(); } else if b1 < a1 { - b = y.next(); + y = y.next(); + b = y.get(); } else { return false; } @@ -283,8 +300,10 @@ impl <T: Ord> TreeSet<T> { let mut x = self.iter(); let mut y = other.iter(); unsafe { // purity workaround - let mut a = x.next(); - let mut b = y.next(); + x = x.next(); + y = y.next(); + let mut a = x.get(); + let mut b = y.get(); while b.is_some() { if a.is_none() { return false @@ -298,9 +317,11 @@ impl <T: Ord> TreeSet<T> { } if !(a1 < b1) { - b = y.next(); + y = y.next(); + b = y.get(); } - a = x.next(); + x = x.next(); + a = x.get(); } } true @@ -312,13 +333,15 @@ impl <T: Ord> TreeSet<T> { let mut y = other.iter(); unsafe { // purity workaround - let mut a = x.next(); - let mut b = y.next(); + x = x.next(); + y = y.next(); + let mut a = x.get(); + let mut b = y.get(); while a.is_some() { if b.is_none() { return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } + if f(a1) { x = x.next(); x.get() } else { None } } } @@ -327,10 +350,12 @@ impl <T: Ord> TreeSet<T> { if a1 < b1 { if !f(a1) { return } - a = x.next(); + x = x.next(); + a = x.get(); } else { - if !(b1 < a1) { a = x.next() } - b = y.next(); + if !(b1 < a1) { x = x.next(); a = x.get() } + y = y.next(); + b = y.get(); } } } @@ -343,13 +368,15 @@ impl <T: Ord> TreeSet<T> { let mut y = other.iter(); unsafe { // purity workaround - let mut a = x.next(); - let mut b = y.next(); + x = x.next(); + y = y.next(); + let mut a = x.get(); + let mut b = y.get(); while a.is_some() { if b.is_none() { return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } + if f(a1) { x.next(); x.get() } else { None } } } @@ -358,18 +385,21 @@ impl <T: Ord> TreeSet<T> { if a1 < b1 { if !f(a1) { return } - a = x.next(); + x = x.next(); + a = x.get(); } else { if b1 < a1 { if !f(b1) { return } } else { - a = x.next(); + x = x.next(); + a = x.get(); } - b = y.next(); + y = y.next(); + b = y.get(); } } do b.while_some |b1| { - if f(b1) { y.next() } else { None } + if f(b1) { y = y.next(); y.get() } else { None } } } } @@ -380,19 +410,23 @@ impl <T: Ord> TreeSet<T> { let mut y = other.iter(); unsafe { // purity workaround - let mut a = x.next(); - let mut b = y.next(); + x = x.next(); + y = y.next(); + let mut a = x.get(); + let mut b = y.get(); while a.is_some() && b.is_some() { let a1 = a.unwrap(); let b1 = b.unwrap(); if a1 < b1 { - a = x.next(); + x = x.next(); + a = x.get(); } else { if !(b1 < a1) { if !f(a1) { return } } - b = y.next(); + y = y.next(); + b = y.get(); } } } @@ -404,13 +438,15 @@ impl <T: Ord> TreeSet<T> { let mut y = other.iter(); unsafe { // purity workaround - let mut a = x.next(); - let mut b = y.next(); + x = x.next(); + y = y.next(); + let mut a = x.get(); + let mut b = y.get(); while a.is_some() { if b.is_none() { return do a.while_some() |a1| { - if f(a1) { x.next() } else { None } + if f(a1) { x = x.next(); x.get() } else { None } } } @@ -419,13 +455,16 @@ impl <T: Ord> TreeSet<T> { if b1 < a1 { if !f(b1) { return } - b = y.next(); + y = y.next(); + b = y.get(); } else { if !f(a1) { return } if !(a1 < b1) { - b = y.next() + y = y.next(); + b = y.get() } - a = x.next(); + x = x.next(); + a = x.get(); } } } @@ -438,11 +477,18 @@ pub struct TreeSetIterator<T: Ord> { } impl <T: Ord> TreeSetIterator<T> { - /// Advance the iterator to the next node (in order) and return a - /// tuple with a reference to the value. If there are no more nodes, - /// return `None`. - fn next(&mut self) -> Option<&self/T> { - self.iter.next().map_consume(|(x, _)| x) + /// Returns the current node, or None if this iterator is at the end. + fn get(&const self) -> Option<&self/T> { + match self.iter.get() { + None => None, + Some((k, _)) => Some(k) + } + } + + /// Advance the iterator to the next node (in order). If this iterator is + /// finished, does nothing. + fn next(self) -> TreeSetIterator/&self<T> { + TreeSetIterator { iter: self.iter.next() } } } @@ -854,17 +900,23 @@ mod test_treemap { //assert iter.next() == Some((&x1, &y1)); //assert iter.next().eq(&Some((&x1, &y1))); - assert iter.next().unwrap() == (&x1, &y1); - assert iter.next().unwrap() == (&x2, &y2); - assert iter.next().unwrap() == (&x3, &y3); - assert iter.next().unwrap() == (&x4, &y4); - assert iter.next().unwrap() == (&x5, &y5); + iter = iter.next(); + assert iter.get().unwrap() == (&x1, &y1); + iter = iter.next(); + assert iter.get().unwrap() == (&x2, &y2); + iter = iter.next(); + assert iter.get().unwrap() == (&x3, &y3); + iter = iter.next(); + assert iter.get().unwrap() == (&x4, &y4); + iter = iter.next(); + assert iter.get().unwrap() == (&x5, &y5); // ICE: //assert iter.next() == None; //assert iter.next().eq(&None); - assert iter.next().is_none(); + iter = iter.next(); + assert iter.get().is_none(); } } |
