diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index a689c66eeaff5..c2b716a4bdf93 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -27,7 +27,7 @@ use core::fmt; use core::hash::{Hasher, Hash}; use core::iter::FromIterator; use core::mem; -use core::ptr; +use core::ptr::Shared; /// A doubly-linked list. #[stable(feature = "rust1", since = "1.0.0")] @@ -40,12 +40,12 @@ pub struct LinkedList { type Link = Option>>; struct Rawlink { - p: *mut T, + p: Option>, } impl Copy for Rawlink {} -unsafe impl Send for Rawlink {} -unsafe impl Sync for Rawlink {} +unsafe impl Send for Rawlink {} +unsafe impl Sync for Rawlink {} struct Node { next: Link, @@ -55,7 +55,7 @@ struct Node { /// An iterator over references to the items of a `LinkedList`. #[stable(feature = "rust1", since = "1.0.0")] -pub struct Iter<'a, T:'a> { +pub struct Iter<'a, T: 'a> { head: &'a Link, tail: Rawlink>, nelem: usize, @@ -64,7 +64,7 @@ pub struct Iter<'a, T:'a> { // FIXME #19839: deriving is too aggressive on the bounds (T doesn't need to be Clone). #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Clone for Iter<'a, T> { - fn clone(&self) -> Iter<'a, T> { + fn clone(&self) -> Self { Iter { head: self.head.clone(), tail: self.tail, @@ -75,7 +75,7 @@ impl<'a, T> Clone for Iter<'a, T> { /// An iterator over mutable references to the items of a `LinkedList`. #[stable(feature = "rust1", since = "1.0.0")] -pub struct IterMut<'a, T:'a> { +pub struct IterMut<'a, T: 'a> { list: &'a mut LinkedList, head: Rawlink>, tail: Rawlink>, @@ -86,19 +86,19 @@ pub struct IterMut<'a, T:'a> { #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - list: LinkedList + list: LinkedList, } /// Rawlink is a type like Option but for holding a raw pointer impl Rawlink { /// Like Option::None for Rawlink - fn none() -> Rawlink { - Rawlink{p: ptr::null_mut()} + fn none() -> Self { + Rawlink { p: None } } /// Like Option::Some for Rawlink - fn some(n: &mut T) -> Rawlink { - Rawlink{p: n} + fn some(n: &mut T) -> Self { + unsafe { Rawlink { p: Some(Shared::new(n)) } } } /// Convert the `Rawlink` into an Option value @@ -108,7 +108,7 @@ impl Rawlink { /// - Dereference of raw pointer. /// - Returns reference of arbitrary lifetime. unsafe fn resolve<'a>(&self) -> Option<&'a T> { - self.p.as_ref() + self.p.map(|p| &**p) } /// Convert the `Rawlink` into an Option value @@ -118,11 +118,11 @@ impl Rawlink { /// - Dereference of raw pointer. /// - Returns reference of arbitrary lifetime. unsafe fn resolve_mut<'a>(&mut self) -> Option<&'a mut T> { - self.p.as_mut() + self.p.map(|p| &mut **p) } /// Return the `Rawlink` and replace with `Rawlink::none()` - fn take(&mut self) -> Rawlink { + fn take(&mut self) -> Self { mem::replace(self, Rawlink::none()) } } @@ -138,14 +138,18 @@ impl<'a, T> From<&'a mut Link> for Rawlink> { impl Clone for Rawlink { #[inline] - fn clone(&self) -> Rawlink { - Rawlink{p: self.p} + fn clone(&self) -> Self { + Rawlink { p: self.p } } } impl Node { - fn new(v: T) -> Node { - Node{value: v, next: None, prev: Rawlink::none()} + fn new(v: T) -> Self { + Node { + value: v, + next: None, + prev: Rawlink::none(), + } } /// Update the `prev` link on `next`, then set self's next pointer. @@ -187,12 +191,12 @@ impl LinkedList { /// Remove the first Node and return it, or None if the list is empty #[inline] - fn pop_front_node(&mut self) -> Option>> { + fn pop_front_node(&mut self) -> Link { self.list_head.take().map(|mut front_node| { self.length -= 1; match front_node.next.take() { Some(node) => self.list_head = link_no_prev(node), - None => self.list_tail = Rawlink::none() + None => self.list_tail = Rawlink::none(), } front_node }) @@ -213,14 +217,14 @@ impl LinkedList { /// Remove the last Node and return it, or None if the list is empty #[inline] - fn pop_back_node(&mut self) -> Option>> { + fn pop_back_node(&mut self) -> Link { unsafe { self.list_tail.resolve_mut().and_then(|tail| { self.length -= 1; self.list_tail = tail.prev; match tail.prev.resolve_mut() { None => self.list_head.take(), - Some(tail_prev) => tail_prev.next.take() + Some(tail_prev) => tail_prev.next.take(), } }) } @@ -230,15 +234,21 @@ impl LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl Default for LinkedList { #[inline] - fn default() -> LinkedList { LinkedList::new() } + fn default() -> Self { + LinkedList::new() + } } impl LinkedList { /// Creates an empty `LinkedList`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn new() -> LinkedList { - LinkedList{list_head: None, list_tail: Rawlink::none(), length: 0} + pub fn new() -> Self { + LinkedList { + list_head: None, + list_tail: Rawlink::none(), + length: 0, + } } /// Moves all elements from `other` to the end of the list. @@ -274,7 +284,7 @@ impl LinkedList { self.length = other.length; self.list_head = other.list_head.take(); self.list_tail = other.list_tail.take(); - }, + } Some(tail) => { // Carefully empty `other`. let o_tail = other.list_tail.take(); @@ -296,7 +306,11 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter { - Iter{nelem: self.len(), head: &self.list_head, tail: self.list_tail} + Iter { + nelem: self.len(), + head: &self.list_head, + tail: self.list_tail, + } } /// Provides a forward iterator with mutable references. @@ -307,7 +321,7 @@ impl LinkedList { nelem: self.len(), head: Rawlink::from(&mut self.list_head), tail: self.list_tail, - list: self + list: self, } } @@ -452,9 +466,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { - unsafe { - self.list_tail.resolve().map(|tail| &tail.value) - } + unsafe { self.list_tail.resolve().map(|tail| &tail.value) } } /// Provides a mutable reference to the back element, or `None` if the list @@ -481,9 +493,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { - unsafe { - self.list_tail.resolve_mut().map(|tail| &mut tail.value) - } + unsafe { self.list_tail.resolve_mut().map(|tail| &mut tail.value) } } /// Adds an element first in the list. @@ -532,7 +542,7 @@ impl LinkedList { /// #[stable(feature = "rust1", since = "1.0.0")] pub fn pop_front(&mut self) -> Option { - self.pop_front_node().map(|box Node{value, ..}| value) + self.pop_front_node().map(|box Node { value, .. }| value) } /// Appends an element to the back of a list @@ -568,7 +578,7 @@ impl LinkedList { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn pop_back(&mut self) -> Option { - self.pop_back_node().map(|box Node{value, ..}| value) + self.pop_back_node().map(|box Node { value, .. }| value) } /// Splits the list into two at the given index. Returns everything after the given index, @@ -617,7 +627,7 @@ impl LinkedList { iter.next(); } iter.head - } else { + } else { // better off starting from the end let mut iter = self.iter_mut(); for _ in 0..len - 1 - (at - 1) { @@ -641,7 +651,7 @@ impl LinkedList { let second_part = LinkedList { list_head: second_part_head, list_tail: self.list_tail, - length: len - at + length: len - at, }; // Fix the tail ptr of the first part @@ -672,7 +682,7 @@ impl<'a, A> Iterator for Iter<'a, A> { type Item = &'a A; #[inline] - fn next(&mut self) -> Option<&'a A> { + fn next(&mut self) -> Option { if self.nelem == 0 { return None; } @@ -713,7 +723,7 @@ impl<'a, A> ExactSizeIterator for Iter<'a, A> {} impl<'a, A> Iterator for IterMut<'a, A> { type Item = &'a mut A; #[inline] - fn next(&mut self) -> Option<&'a mut A> { + fn next(&mut self) -> Option { if self.nelem == 0 { return None; } @@ -760,7 +770,9 @@ impl<'a, A> IterMut<'a, A> { // // The inserted node will not appear in further iteration. match unsafe { self.head.resolve_mut() } { - None => { self.list.push_back_node(ins_node); } + None => { + self.list.push_back_node(ins_node); + } Some(node) => { let prev_node = match unsafe { node.prev.resolve_mut() } { None => return self.list.push_front_node(ins_node), @@ -830,11 +842,9 @@ impl<'a, A> IterMut<'a, A> { issue = "27794")] pub fn peek_next(&mut self) -> Option<&mut A> { if self.nelem == 0 { - return None - } - unsafe { - self.head.resolve_mut().map(|head| &mut head.value) + return None; } + unsafe { self.head.resolve_mut().map(|head| &mut head.value) } } } @@ -843,7 +853,9 @@ impl Iterator for IntoIter { type Item = A; #[inline] - fn next(&mut self) -> Option { self.list.pop_front() } + fn next(&mut self) -> Option { + self.list.pop_front() + } #[inline] fn size_hint(&self) -> (usize, Option) { @@ -854,7 +866,9 @@ impl Iterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { #[inline] - fn next_back(&mut self) -> Option { self.list.pop_back() } + fn next_back(&mut self) -> Option { + self.list.pop_back() + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -862,7 +876,7 @@ impl ExactSizeIterator for IntoIter {} #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for LinkedList { - fn from_iter>(iter: T) -> LinkedList { + fn from_iter>(iter: T) -> Self { let mut ret = LinkedList::new(); ret.extend(iter); ret @@ -872,21 +886,21 @@ impl FromIterator for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl IntoIterator for LinkedList { type Item = T; - type IntoIter = IntoIter; + type IntoIter = IntoIter; /// Consumes the list into an iterator yielding elements by value. #[inline] - fn into_iter(self) -> IntoIter { - IntoIter{list: self} + fn into_iter(self) -> Self::IntoIter { + IntoIter { list: self } } } #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> IntoIterator for &'a LinkedList { type Item = &'a T; - type IntoIter = Iter<'a, T>; + type IntoIter = Iter; - fn into_iter(self) -> Iter<'a, T> { + fn into_iter(self) -> Self::IntoIter { self.iter() } } @@ -903,28 +917,28 @@ impl<'a, T> IntoIterator for &'a mut LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl Extend for LinkedList { - fn extend>(&mut self, iter: T) { - for elt in iter { self.push_back(elt); } + fn extend>(&mut self, iter: T) { + for elt in iter { + self.push_back(elt); + } } } #[stable(feature = "extend_ref", since = "1.2.0")] impl<'a, T: 'a + Copy> Extend<&'a T> for LinkedList { - fn extend>(&mut self, iter: I) { + fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } } #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for LinkedList { - fn eq(&self, other: &LinkedList) -> bool { - self.len() == other.len() && - self.iter().eq(other.iter()) + fn eq(&self, other: &Self) -> bool { + self.len() == other.len() && self.iter().eq(other.iter()) } fn ne(&self, other: &LinkedList) -> bool { - self.len() != other.len() || - self.iter().ne(other.iter()) + self.len() != other.len() || self.iter().ne(other.iter()) } } @@ -933,7 +947,7 @@ impl Eq for LinkedList {} #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for LinkedList { - fn partial_cmp(&self, other: &LinkedList) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { self.iter().partial_cmp(other.iter()) } } @@ -948,7 +962,7 @@ impl Ord for LinkedList { #[stable(feature = "rust1", since = "1.0.0")] impl Clone for LinkedList { - fn clone(&self) -> LinkedList { + fn clone(&self) -> Self { self.iter().cloned().collect() } } @@ -970,11 +984,19 @@ impl Hash for LinkedList { } } +// Ensure that `LinkedList` and its read-only iterators are covariant in their type parameters. +#[allow(dead_code)] +fn assert_covariance() { + fn a<'a>(x: LinkedList<&'static str>) -> LinkedList<&'a str> { x } + fn b<'i, 'a>(x: Iter<'i, &'static str>) -> Iter<'i, &'a str> { x } + fn c<'a>(x: IntoIter<&'static str>) -> IntoIter<&'a str> { x } +} + #[cfg(test)] mod tests { use std::clone::Clone; use std::iter::{Iterator, IntoIterator, Extend}; - use std::option::Option::{Some, None, self}; + use std::option::Option::{self, Some, None}; use std::__rand::{thread_rng, Rng}; use std::thread; use std::vec::Vec; @@ -991,13 +1013,16 @@ mod tests { let mut last_ptr: Option<&Node> = None; let mut node_ptr: &Node; match list.list_head { - None => { assert_eq!(0, list.length); return } + None => { + assert_eq!(0, list.length); + return; + } Some(ref node) => node_ptr = &**node, } loop { match unsafe { (last_ptr, node_ptr.prev.resolve()) } { - (None , None ) => {} - (None , _ ) => panic!("prev link for list_head"), + (None, None) => {} + (None, _) => panic!("prev link for list_head"), (Some(p), Some(pptr)) => { assert_eq!(p as *const Node, pptr as *const Node); } @@ -1054,8 +1079,8 @@ mod tests { } // Non-empty to non-empty - let v = vec![1,2,3,4,5]; - let u = vec![9,8,1,2,3,4,5]; + let v = vec![1, 2, 3, 4, 5]; + let u = vec![9, 8, 1, 2, 3, 4, 5]; let mut m = list_from(&v); let mut n = list_from(&u); m.append(&mut n); @@ -1077,7 +1102,7 @@ mod tests { #[test] fn test_insert_prev() { - let mut m = list_from(&[0,2,4,6,8]); + let mut m = list_from(&[0, 2, 4, 6, 8]); let len = m.len(); { let mut it = m.iter_mut(); @@ -1099,17 +1124,21 @@ mod tests { } check_links(&m); assert_eq!(m.len(), 3 + len * 2); - assert_eq!(m.into_iter().collect::>(), [-2,0,1,2,3,4,5,6,7,8,9,0,1]); + assert_eq!(m.into_iter().collect::>(), + [-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1]); } #[test] fn test_send() { - let n = list_from(&[1,2,3]); + let n = list_from(&[1, 2, 3]); thread::spawn(move || { check_links(&n); - let a: &[_] = &[&1,&2,&3]; + let a: &[_] = &[&1, &2, &3]; assert_eq!(a, &n.iter().collect::>()[..]); - }).join().ok().unwrap(); + }) + .join() + .ok() + .unwrap(); } #[test] @@ -1179,7 +1208,7 @@ mod tests { v.remove(0); } } - 2 | 4 => { + 2 | 4 => { m.push_front(-i); v.insert(0, -i); }