Skip to content

Fix overly permissive borrow checking rules for &mut &mut #10519

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/libextra/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,9 @@ impl<T> Deque<T> for DList<T> {
/// Provide a mutable reference to the back element, or None if the list is empty
#[inline]
fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
let mut tmp = self.list_tail.resolve(); // FIXME: #3511: shouldn't need variable
tmp.as_mut().map(|tail| &mut tail.value)
let tmp: Option<&'a mut Node<T>> =
self.list_tail.resolve(); // FIXME: #3511: shouldn't need variable
tmp.map(|tail| &mut tail.value)
}

/// Add an element first in the list
Expand Down
155 changes: 108 additions & 47 deletions src/libextra/ringbuf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,28 @@ impl<T> RingBuf<T> {

/// Front-to-back iterator which returns mutable values.
pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> {
RingBufMutIterator{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts}
let start_index = raw_index(self.lo, self.elts.len(), 0);
let end_index = raw_index(self.lo, self.elts.len(), self.nelts);

// Divide up the array
if end_index <= start_index {
// Items to iterate goes from:
// start_index to self.elts.len()
// and then
// 0 to end_index
let (temp, remaining1) = self.elts.mut_split(start_index);
let (remaining2, _) = temp.mut_split(end_index);
RingBufMutIterator { remaining1: remaining1,
remaining2: remaining2,
nelts: self.nelts }
} else {
// Items to iterate goes from start_index to end_index:
let (empty, elts) = self.elts.mut_split(0);
let remaining1 = elts.mut_slice(start_index, end_index);
RingBufMutIterator { remaining1: remaining1,
remaining2: empty,
nelts: self.nelts }
}
}

/// Back-to-front iterator which returns mutable values.
Expand All @@ -207,54 +228,43 @@ impl<T> RingBuf<T> {
}
}

macro_rules! iterator {
(impl $name:ident -> $elem:ty, $getter:ident) => {
impl<'self, T> Iterator<$elem> for $name<'self, T> {
#[inline]
fn next(&mut self) -> Option<$elem> {
if self.index == self.rindex {
return None;
}
let raw_index = raw_index(self.lo, self.elts.len(), self.index);
self.index += 1;
Some(self.elts[raw_index] . $getter ())
}
/// RingBuf iterator
pub struct RingBufIterator<'self, T> {
priv lo: uint,
priv index: uint,
priv rindex: uint,
priv elts: &'self [Option<T>],
}

#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let len = self.rindex - self.index;
(len, Some(len))
}
impl<'self, T> Iterator<&'self T> for RingBufIterator<'self, T> {
#[inline]
fn next(&mut self) -> Option<&'self T> {
if self.index == self.rindex {
return None;
}
let raw_index = raw_index(self.lo, self.elts.len(), self.index);
self.index += 1;
Some(self.elts[raw_index].get_ref())
}
}

macro_rules! iterator_rev {
(impl $name:ident -> $elem:ty, $getter:ident) => {
impl<'self, T> DoubleEndedIterator<$elem> for $name<'self, T> {
#[inline]
fn next_back(&mut self) -> Option<$elem> {
if self.index == self.rindex {
return None;
}
self.rindex -= 1;
let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
Some(self.elts[raw_index] . $getter ())
}
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
let len = self.rindex - self.index;
(len, Some(len))
}
}


/// RingBuf iterator
pub struct RingBufIterator<'self, T> {
priv lo: uint,
priv index: uint,
priv rindex: uint,
priv elts: &'self [Option<T>],
impl<'self, T> DoubleEndedIterator<&'self T> for RingBufIterator<'self, T> {
#[inline]
fn next_back(&mut self) -> Option<&'self T> {
if self.index == self.rindex {
return None;
}
self.rindex -= 1;
let raw_index = raw_index(self.lo, self.elts.len(), self.rindex);
Some(self.elts[raw_index].get_ref())
}
}
iterator!{impl RingBufIterator -> &'self T, get_ref}
iterator_rev!{impl RingBufIterator -> &'self T, get_ref}

impl<'self, T> ExactSize<&'self T> for RingBufIterator<'self, T> {}

Expand All @@ -275,13 +285,49 @@ impl<'self, T> RandomAccessIterator<&'self T> for RingBufIterator<'self, T> {

/// RingBuf mutable iterator
pub struct RingBufMutIterator<'self, T> {
priv lo: uint,
priv index: uint,
priv rindex: uint,
priv elts: &'self mut [Option<T>],
priv remaining1: &'self mut [Option<T>],
priv remaining2: &'self mut [Option<T>],
priv nelts: uint,
}

impl<'self, T> Iterator<&'self mut T> for RingBufMutIterator<'self, T> {
#[inline]
fn next(&mut self) -> Option<&'self mut T> {
if self.nelts == 0 {
return None;
}
let r = if self.remaining1.len() > 0 {
&mut self.remaining1
} else {
assert!(self.remaining2.len() > 0);
&mut self.remaining2
};
self.nelts -= 1;
Some(r.mut_shift_ref().get_mut_ref())
}

#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
(self.nelts, Some(self.nelts))
}
}

impl<'self, T> DoubleEndedIterator<&'self mut T> for RingBufMutIterator<'self, T> {
#[inline]
fn next_back(&mut self) -> Option<&'self mut T> {
if self.nelts == 0 {
return None;
}
let r = if self.remaining2.len() > 0 {
&mut self.remaining2
} else {
assert!(self.remaining1.len() > 0);
&mut self.remaining1
};
self.nelts -= 1;
Some(r.mut_pop_ref().get_mut_ref())
}
}
iterator!{impl RingBufMutIterator -> &'self mut T, get_mut_ref}
iterator_rev!{impl RingBufMutIterator -> &'self mut T, get_mut_ref}

impl<'self, T> ExactSize<&'self mut T> for RingBufMutIterator<'self, T> {}

Expand Down Expand Up @@ -667,6 +713,21 @@ mod tests {
assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]);
}

#[test]
fn test_mut_rev_iter_wrap() {
let mut d = RingBuf::with_capacity(3);
assert!(d.mut_rev_iter().next().is_none());

d.push_back(1);
d.push_back(2);
d.push_back(3);
assert_eq!(d.pop_front(), Some(1));
d.push_back(4);

assert_eq!(d.mut_rev_iter().map(|x| *x).collect::<~[int]>(),
~[4, 3, 2]);
}

#[test]
fn test_mut_iter() {
let mut d = RingBuf::new();
Expand Down
Loading