librustc: Allow &mut to be loaned; allow self to be loaned; make &mut loanable to &. r=nmatsakis
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user