diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index efa96ca468e01..a28578e305b42 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -941,7 +941,7 @@ impl<'a, T> Hole<'a, T> { /// Unsafe because index must be within the data slice and not equal to pos. #[inline] unsafe fn get(&self, index: usize) -> &T { - debug_assert!(index != self.pos); + debug_assert_ne!(index, self.pos); debug_assert!(index < self.data.len()); self.data.get_unchecked(index) } @@ -951,7 +951,7 @@ impl<'a, T> Hole<'a, T> { /// Unsafe because index must be within the data slice and not equal to pos. #[inline] unsafe fn move_to(&mut self, index: usize) { - debug_assert!(index != self.pos); + debug_assert_ne!(index, self.pos); debug_assert!(index < self.data.len()); let index_ptr: *const _ = self.data.get_unchecked(index); let hole_ptr = self.data.get_unchecked_mut(self.pos); @@ -1194,8 +1194,8 @@ impl> SpecExtend for BinaryHeap { } impl SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: BinaryHeap) { - self.append(other); + fn spec_extend(&mut self, mut other: BinaryHeap) { + self.append(&mut other); } } diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs index 65056121f05a0..d625a94fe072d 100644 --- a/src/libcollections/borrow.rs +++ b/src/libcollections/borrow.rs @@ -254,7 +254,7 @@ impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Borrowed(ref b) => fmt::Debug::fmt(b, f), + Borrowed(b) => fmt::Debug::fmt(b, f), Owned(ref o) => fmt::Debug::fmt(o, f), } } @@ -267,7 +267,7 @@ impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { - Borrowed(ref b) => fmt::Display::fmt(b, f), + Borrowed(b) => fmt::Display::fmt(b, f), Owned(ref o) => fmt::Display::fmt(o, f), } } diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index dcacef4f0f0d5..f95bc2dc60dee 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -262,7 +262,7 @@ impl super::Recover for BTreeMap } } -/// An iterator over a BTreeMap's entries. +/// An iterator over a `BTreeMap`'s entries. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, K: 'a, V: 'a> { range: Range<'a, K, V>, @@ -276,7 +276,7 @@ impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Iter<'a, K, V> { } } -/// A mutable iterator over a BTreeMap's entries. +/// A mutable iterator over a `BTreeMap`'s entries. #[stable(feature = "rust1", since = "1.0.0")] #[derive(Debug)] pub struct IterMut<'a, K: 'a, V: 'a> { @@ -284,7 +284,7 @@ pub struct IterMut<'a, K: 'a, V: 'a> { length: usize, } -/// An owning iterator over a BTreeMap's entries. +/// An owning iterator over a `BTreeMap`'s entries. #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { front: Handle, marker::Edge>, @@ -303,7 +303,7 @@ impl fmt::Debug for IntoIter { } } -/// An iterator over a BTreeMap's keys. +/// An iterator over a `BTreeMap`'s keys. #[stable(feature = "rust1", since = "1.0.0")] pub struct Keys<'a, K: 'a, V: 'a> { inner: Iter<'a, K, V>, @@ -316,7 +316,7 @@ impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Keys<'a, K, V> { } } -/// An iterator over a BTreeMap's values. +/// An iterator over a `BTreeMap`'s values. #[stable(feature = "rust1", since = "1.0.0")] pub struct Values<'a, K: 'a, V: 'a> { inner: Iter<'a, K, V>, @@ -329,14 +329,14 @@ impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Values<'a, K, V> } } -/// A mutable iterator over a BTreeMap's values. +/// A mutable iterator over a `BTreeMap`'s values. #[stable(feature = "map_values_mut", since = "1.10.0")] #[derive(Debug)] pub struct ValuesMut<'a, K: 'a, V: 'a> { inner: IterMut<'a, K, V>, } -/// An iterator over a sub-range of BTreeMap's entries. +/// An iterator over a sub-range of `BTreeMap`'s entries. #[stable(feature = "btree_range", since = "1.17.0")] pub struct Range<'a, K: 'a, V: 'a> { front: Handle, K, V, marker::Leaf>, marker::Edge>, @@ -350,7 +350,7 @@ impl<'a, K: 'a + fmt::Debug, V: 'a + fmt::Debug> fmt::Debug for Range<'a, K, V> } } -/// A mutable iterator over a sub-range of BTreeMap's entries. +/// A mutable iterator over a sub-range of `BTreeMap`'s entries. #[stable(feature = "btree_range", since = "1.17.0")] pub struct RangeMut<'a, K: 'a, V: 'a> { front: Handle, K, V, marker::Leaf>, marker::Edge>, @@ -685,12 +685,12 @@ impl BTreeMap { #[stable(feature = "btree_append", since = "1.11.0")] pub fn append(&mut self, other: &mut Self) { // Do we have to append anything at all? - if other.len() == 0 { + if other.is_empty() { return; } // We can just swap `self` and `other` if `self` is empty. - if self.len() == 0 { + if self.is_empty() { mem::swap(self, other); return; } @@ -1894,7 +1894,7 @@ impl BTreeMap { /// assert_eq!(keys, [1, 2]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn keys<'a>(&'a self) -> Keys<'a, K, V> { + pub fn keys(&self) -> Keys { Keys { inner: self.iter() } } @@ -1915,7 +1915,7 @@ impl BTreeMap { /// assert_eq!(values, ["hello", "goodbye"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn values<'a>(&'a self) -> Values<'a, K, V> { + pub fn values(&self) -> Values { Values { inner: self.iter() } } @@ -2354,8 +2354,8 @@ enum UnderflowResult<'a, K, V> { Stole(NodeRef, K, V, marker::Internal>), } -fn handle_underfull_node<'a, K, V>(node: NodeRef, K, V, marker::LeafOrInternal>) - -> UnderflowResult<'a, K, V> { +fn handle_underfull_node(node: NodeRef) + -> UnderflowResult { let parent = if let Ok(parent) = node.ascend() { parent } else { diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index e9bc29118d508..e4cee815315fc 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -347,7 +347,7 @@ impl NodeRef { } /// Temporarily takes out another, immutable reference to the same node. - fn reborrow<'a>(&'a self) -> NodeRef, K, V, Type> { + fn reborrow(&self) -> NodeRef { NodeRef { height: self.height, node: self.node, @@ -964,7 +964,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: fn insert_fit(&mut self, key: K, val: V, edge: Root) { // Necessary for correctness, but in an internal module debug_assert!(self.node.len() < CAPACITY); - debug_assert!(edge.height == self.node.height - 1); + debug_assert_eq!(edge.height, self.node.height - 1); unsafe { // This cast is a lie, but it allows us to reuse the key/value insertion logic. @@ -992,7 +992,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: -> InsertResult<'a, K, V, marker::Internal> { // Necessary for correctness, but this is an internal module - debug_assert!(edge.height == self.node.height - 1); + debug_assert_eq!(edge.height, self.node.height - 1); if self.node.len() < CAPACITY { self.insert_fit(key, val, edge); @@ -1488,8 +1488,8 @@ impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, ma let right_new_len = left_node.len() - left_new_len; let mut right_node = right.reborrow_mut(); - debug_assert!(right_node.len() == 0); - debug_assert!(left_node.height == right_node.height); + debug_assert_eq!(right_node.len(), 0); + debug_assert_eq!(left_node.height, right_node.height); let left_kv = left_node.reborrow_mut().into_kv_pointers_mut(); let right_kv = right_node.reborrow_mut().into_kv_pointers_mut(); diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 9dbb61379379e..acb38ccec0fc7 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -1053,7 +1053,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> { fn next(&mut self) -> Option<&'a T> { loop { let o_cmp = match (self.a.peek(), self.b.peek()) { - (None, _) => None, + (None, _) | (_, None) => None, (Some(a1), Some(b1)) => Some(a1.cmp(b1)), }; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index e56b94b2e1ea2..ebee75d1a1a64 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -215,7 +215,7 @@ impl BitXor for EnumSet { } } -/// An iterator over an EnumSet +/// An iterator over an `EnumSet` pub struct Iter { index: usize, bits: usize, diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 00448b6abb2cf..c55e63a5b2f04 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -10,7 +10,7 @@ //! Collection types. //! -//! See [std::collections](../std/collections/index.html) for a detailed discussion of +//! See [`std::collections`](../std/collections/index.html) for a detailed discussion of //! collections in Rust. #![crate_name = "collections"] diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs index 8f0488f69369e..4b5d5510fdf25 100644 --- a/src/libcollections/linked_list.rs +++ b/src/libcollections/linked_list.rs @@ -95,7 +95,7 @@ pub struct IterMut<'a, T: 'a> { impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IterMut") - .field(self.clone()) + .field(self) .finish() } } @@ -111,7 +111,7 @@ pub struct IntoIter { impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IntoIter") - .field(self.clone()) + .field(self) .finish() } } @@ -1020,8 +1020,8 @@ impl SpecExtend for LinkedList { } impl SpecExtend> for LinkedList { - fn spec_extend(&mut self, ref mut other: LinkedList) { - self.append(other); + fn spec_extend(&mut self, mut other: LinkedList) { + self.append(&mut other); } } @@ -1110,7 +1110,7 @@ pub struct FrontPlace<'a, T: 'a> { impl<'a, T: 'a + fmt::Debug> fmt::Debug for FrontPlace<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("FrontPlace") - .field(self.clone()) + .field(self) .finish() } } @@ -1165,7 +1165,7 @@ pub struct BackPlace<'a, T: 'a> { impl<'a, T: 'a + fmt::Debug> fmt::Debug for BackPlace<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("BackPlace") - .field(self.clone()) + .field(self) .finish() } } diff --git a/src/libcollections/range.rs b/src/libcollections/range.rs index 06d89a6a70b4a..48d208f6efa8d 100644 --- a/src/libcollections/range.rs +++ b/src/libcollections/range.rs @@ -17,7 +17,7 @@ use core::ops::{RangeFull, Range, RangeTo, RangeFrom, RangeInclusive, RangeToInclusive}; use Bound::{self, Excluded, Included, Unbounded}; -/// **RangeArgument** is implemented by Rust's built-in range types, produced +/// **`RangeArgument`** is implemented by Rust's built-in range types, produced /// by range syntax like `..`, `a..`, `..b` or `c..d`. pub trait RangeArgument { /// Start index bound. diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 6f8843c2374bc..cdfdd6cf78c35 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -1651,7 +1651,7 @@ unsafe fn merge(v: &mut [T], mid: usize, buf: *mut T, is_less: &mut F) } } -/// This merge sort borrows some (but not all) ideas from TimSort, which is described in detail +/// This merge sort borrows some (but not all) ideas from `TimSort`, which is described in detail /// [here](http://svn.python.org/projects/python/trunk/Objects/listsort.txt). /// /// The algorithm identifies strictly descending and non-descending subsequences, which are called diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 72db452093fc2..5f19b1fe8650a 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -133,9 +133,15 @@ impl> SliceConcatExt for [S] { } } -/// External iterator for a string's UTF-16 code units. +/// An iterator of [`u16`] over the string encoded as UTF-16. /// -/// For use with the `std::iter` module. +/// [`u16`]: ../../std/primitive.u16.html +/// +/// This struct is created by the [`encode_utf16`] method on [`str`]. +/// See its documentation for more. +/// +/// [`encode_utf16`]: ../../std/primitive.str.html#method.encode_utf16 +/// [`str`]: ../../std/primitive.str.html #[derive(Clone)] #[stable(feature = "encode_utf16", since = "1.8.0")] pub struct EncodeUtf16<'a> { @@ -1829,7 +1835,7 @@ impl str { fn map_uppercase_sigma(from: &str, i: usize, to: &mut String) { // See http://www.unicode.org/versions/Unicode7.0.0/ch03.pdf#G33992 // for the definition of `Final_Sigma`. - debug_assert!('Σ'.len_utf8() == 2); + debug_assert_eq!('Σ'.len_utf8(), 2); let is_word_final = case_ignoreable_then_cased(from[..i].chars().rev()) && !case_ignoreable_then_cased(from[i + 2..].chars()); to.push_str(if is_word_final { "ς" } else { "σ" }); @@ -1876,7 +1882,7 @@ impl str { pub fn to_uppercase(&self) -> String { let mut s = String::with_capacity(self.len()); s.extend(self.chars().flat_map(|c| c.to_uppercase())); - return s; + s } /// Escapes each char in `s` with `char::escape_debug`. diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 0ee4c8b8e95a6..fdc5dd5e4a394 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -533,7 +533,7 @@ impl String { /// assert_eq!("Hello �World", output); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> { + pub fn from_utf8_lossy(v: &[u8]) -> Cow { let mut i; match str::from_utf8(v) { Ok(s) => return Cow::Borrowed(s), @@ -591,9 +591,9 @@ impl String { } 3 => { match (byte, safe_get(v, i, total)) { - (0xE0, 0xA0...0xBF) => (), - (0xE1...0xEC, 0x80...0xBF) => (), - (0xED, 0x80...0x9F) => (), + (0xE0, 0xA0...0xBF) | + (0xE1...0xEC, 0x80...0xBF) | + (0xED, 0x80...0x9F) | (0xEE...0xEF, 0x80...0xBF) => (), _ => { error!(); @@ -609,8 +609,8 @@ impl String { } 4 => { match (byte, safe_get(v, i, total)) { - (0xF0, 0x90...0xBF) => (), - (0xF1...0xF3, 0x80...0xBF) => (), + (0xF0, 0x90...0xBF) | + (0xF1...0xF3, 0x80...0xBF) | (0xF4, 0x80...0x8F) => (), _ => { error!(); diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 56b60a3e00341..b2ea35a6b61a3 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -2052,21 +2052,19 @@ impl Iterator for IntoIter { unsafe { if self.ptr as *const _ == self.end { None + } else if mem::size_of::() == 0 { + // purposefully don't use 'ptr.offset' because for + // vectors with 0-size elements this would return the + // same pointer. + self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T; + + // Use a non-null pointer value + Some(ptr::read(EMPTY as *mut T)) } else { - if mem::size_of::() == 0 { - // purposefully don't use 'ptr.offset' because for - // vectors with 0-size elements this would return the - // same pointer. - self.ptr = arith_offset(self.ptr as *const i8, 1) as *mut T; - - // Use a non-null pointer value - Some(ptr::read(EMPTY as *mut T)) - } else { - let old = self.ptr; - self.ptr = self.ptr.offset(1); - - Some(ptr::read(old)) - } + let old = self.ptr; + self.ptr = self.ptr.offset(1); + + Some(ptr::read(old)) } } } @@ -2097,18 +2095,16 @@ impl DoubleEndedIterator for IntoIter { unsafe { if self.end == self.ptr { None - } else { - if mem::size_of::() == 0 { - // See above for why 'ptr.offset' isn't used - self.end = arith_offset(self.end as *const i8, -1) as *mut T; + } else if mem::size_of::() == 0 { + // See above for why 'ptr.offset' isn't used + self.end = arith_offset(self.end as *const i8, -1) as *mut T; - // Use a non-null pointer value - Some(ptr::read(EMPTY as *mut T)) - } else { - self.end = self.end.offset(-1); + // Use a non-null pointer value + Some(ptr::read(EMPTY as *mut T)) + } else { + self.end = self.end.offset(-1); - Some(ptr::read(self.end)) - } + Some(ptr::read(self.end)) } } } diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs index cb92236ec736c..40bb4ced36660 100644 --- a/src/libcollections/vec_deque.rs +++ b/src/libcollections/vec_deque.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! VecDeque is a double-ended queue, which is implemented with the help of a +//! `VecDeque` is a double-ended queue, which is implemented with the help of a //! growing ring buffer. //! //! This queue has `O(1)` amortized inserts and removals from both ends of the @@ -357,7 +357,7 @@ impl VecDeque { } debug_assert!(self.head < self.cap()); debug_assert!(self.tail < self.cap()); - debug_assert!(self.cap().count_ones() == 1); + debug_assert_eq!(self.cap().count_ones(), 1); } } @@ -631,7 +631,7 @@ impl VecDeque { debug_assert!(self.head < self.cap()); debug_assert!(self.tail < self.cap()); - debug_assert!(self.cap().count_ones() == 1); + debug_assert_eq!(self.cap().count_ones(), 1); } } @@ -1614,7 +1614,7 @@ impl VecDeque { } } - return elem; + elem } /// Splits the collection into two at the given index. @@ -1847,7 +1847,7 @@ fn wrap_index(index: usize, size: usize) -> usize { index & (size - 1) } -/// Returns the two slices that cover the VecDeque's valid range +/// Returns the two slices that cover the `VecDeque`'s valid range trait RingSlices: Sized { fn slice(self, from: usize, to: usize) -> Self; fn split_at(self, i: usize) -> (Self, Self); @@ -1983,7 +1983,7 @@ pub struct IterMut<'a, T: 'a> { impl<'a, T: 'a + fmt::Debug> fmt::Debug for IterMut<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IterMut") - .field(&self.clone()) + .field(&self) .finish() } } @@ -2047,7 +2047,7 @@ impl<'a, T> ExactSizeIterator for IterMut<'a, T> { #[unstable(feature = "fused", issue = "35602")] impl<'a, T> FusedIterator for IterMut<'a, T> {} -/// A by-value VecDeque iterator +/// A by-value `VecDeque` iterator #[derive(Clone)] #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { @@ -2058,7 +2058,7 @@ pub struct IntoIter { impl fmt::Debug for IntoIter { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("IntoIter") - .field(&self.clone()) + .field(&self) .finish() } } @@ -2097,7 +2097,7 @@ impl ExactSizeIterator for IntoIter { #[unstable(feature = "fused", issue = "35602")] impl FusedIterator for IntoIter {} -/// A draining VecDeque iterator +/// A draining `VecDeque` iterator #[stable(feature = "drain", since = "1.6.0")] pub struct Drain<'a, T: 'a> { after_tail: usize, @@ -2110,7 +2110,7 @@ pub struct Drain<'a, T: 'a> { impl<'a, T: 'a + fmt::Debug> fmt::Debug for Drain<'a, T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Drain") - .field(&self.clone()) + .field(&self) .finish() } } @@ -2426,57 +2426,54 @@ impl From> for Vec { // Need to move the ring to the front of the buffer, as vec will expect this. if other.is_contiguous() { ptr::copy(buf.offset(tail as isize), buf, len); - } else { - if (tail - head) >= cmp::min((cap - tail), head) { - // There is enough free space in the centre for the shortest block so we can - // do this in at most three copy moves. - if (cap - tail) > head { - // right hand block is the long one; move that enough for the left - ptr::copy(buf.offset(tail as isize), - buf.offset((tail - head) as isize), - cap - tail); - // copy left in the end - ptr::copy(buf, buf.offset((cap - head) as isize), head); - // shift the new thing to the start - ptr::copy(buf.offset((tail - head) as isize), buf, len); - } else { - // left hand block is the long one, we can do it in two! - ptr::copy(buf, buf.offset((cap - tail) as isize), head); - ptr::copy(buf.offset(tail as isize), buf, cap - tail); - } + } else if (tail - head) >= cmp::min((cap - tail), head) { + // There is enough free space in the centre for the shortest block so we can + // do this in at most three copy moves. + if (cap - tail) > head { + // right hand block is the long one; move that enough for the left + ptr::copy(buf.offset(tail as isize), + buf.offset((tail - head) as isize), + cap - tail); + // copy left in the end + ptr::copy(buf, buf.offset((cap - head) as isize), head); + // shift the new thing to the start + ptr::copy(buf.offset((tail - head) as isize), buf, len); } else { - // Need to use N swaps to move the ring - // We can use the space at the end of the ring as a temp store - - let mut left_edge: usize = 0; - let mut right_edge: usize = tail; - - // The general problem looks like this - // GHIJKLM...ABCDEF - before any swaps - // ABCDEFM...GHIJKL - after 1 pass of swaps - // ABCDEFGHIJM...KL - swap until the left edge reaches the temp store - // - then restart the algorithm with a new (smaller) store - // Sometimes the temp store is reached when the right edge is at the end - // of the buffer - this means we've hit the right order with fewer swaps! - // E.g - // EF..ABCD - // ABCDEF.. - after four only swaps we've finished - - while left_edge < len && right_edge != cap { - let mut right_offset = 0; - for i in left_edge..right_edge { - right_offset = (i - left_edge) % (cap - right_edge); - let src: isize = (right_edge + right_offset) as isize; - ptr::swap(buf.offset(i as isize), buf.offset(src)); - } - let n_ops = right_edge - left_edge; - left_edge += n_ops; - right_edge += right_offset + 1; - + // left hand block is the long one, we can do it in two! + ptr::copy(buf, buf.offset((cap - tail) as isize), head); + ptr::copy(buf.offset(tail as isize), buf, cap - tail); + } + } else { + // Need to use N swaps to move the ring + // We can use the space at the end of the ring as a temp store + + let mut left_edge: usize = 0; + let mut right_edge: usize = tail; + + // The general problem looks like this + // GHIJKLM...ABCDEF - before any swaps + // ABCDEFM...GHIJKL - after 1 pass of swaps + // ABCDEFGHIJM...KL - swap until the left edge reaches the temp store + // - then restart the algorithm with a new (smaller) store + // Sometimes the temp store is reached when the right edge is at the end + // of the buffer - this means we've hit the right order with fewer swaps! + // E.g + // EF..ABCD + // ABCDEF.. - after four only swaps we've finished + + while left_edge < len && right_edge != cap { + let mut right_offset = 0; + for i in left_edge..right_edge { + right_offset = (i - left_edge) % (cap - right_edge); + let src: isize = (right_edge + right_offset) as isize; + ptr::swap(buf.offset(i as isize), buf.offset(src)); } + let n_ops = right_edge - left_edge; + left_edge += n_ops; + right_edge += right_offset + 1; } - } + let out = Vec::from_raw_parts(buf, len, cap); mem::forget(other); out diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs index 00d4dbe9c0458..c3e5304fb2b35 100644 --- a/src/libcollectionstest/slice.rs +++ b/src/libcollectionstest/slice.rs @@ -383,9 +383,11 @@ fn test_reverse() { #[test] fn test_sort() { + let mut rng = thread_rng(); + for len in (2..25).chain(500..510) { for _ in 0..100 { - let mut v: Vec<_> = thread_rng().gen_iter::().take(len).collect(); + let mut v: Vec<_> = rng.gen_iter::().take(len).collect(); let mut v1 = v.clone(); v.sort(); @@ -399,6 +401,18 @@ fn test_sort() { } } + // Sort using a completely random comparison function. + // This will reorder the elements *somehow*, but won't panic. + let mut v = [0; 500]; + for i in 0..v.len() { + v[i] = i as i32; + } + v.sort_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap()); + v.sort(); + for i in 0..v.len() { + assert_eq!(v[i], i as i32); + } + // Should not panic. [0i32; 0].sort(); [(); 10].sort(); diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 5056adeaeeec3..f75a1f7ab6e0f 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -369,11 +369,15 @@ impl fmt::Display for Utf8Error { Section: Iterators */ -/// Iterator for the char (representing *Unicode Scalar Values*) of a string. +/// An iterator over the [`char`]s of a string slice. /// -/// Created with the method [`chars`]. +/// [`char`]: ../../std/primitive.char.html +/// +/// This struct is created by the [`chars`] method on [`str`]. +/// See its documentation for more. /// /// [`chars`]: ../../std/primitive.str.html#method.chars +/// [`str`]: ../../std/primitive.str.html #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct Chars<'a> { @@ -553,7 +557,15 @@ impl<'a> Chars<'a> { } } -/// Iterator for a string's characters and their byte offsets. +/// An iterator over the [`char`]s of a string slice, and their positions. +/// +/// [`char`]: ../../std/primitive.char.html +/// +/// This struct is created by the [`char_indices`] method on [`str`]. +/// See its documentation for more. +/// +/// [`char_indices`]: ../../std/primitive.str.html#method.char_indices +/// [`str`]: ../../std/primitive.str.html #[derive(Clone, Debug)] #[stable(feature = "rust1", since = "1.0.0")] pub struct CharIndices<'a> { @@ -625,12 +637,13 @@ impl<'a> CharIndices<'a> { } } -/// External iterator for a string's bytes. -/// Use with the `std::iter` module. +/// An iterator over the bytes of a string slice. /// -/// Created with the method [`bytes`]. +/// This struct is created by the [`bytes`] method on [`str`]. +/// See its documentation for more. /// /// [`bytes`]: ../../std/primitive.str.html#method.bytes +/// [`str`]: ../../std/primitive.str.html #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] pub struct Bytes<'a>(Cloned>); @@ -1161,9 +1174,13 @@ generate_pattern_iterators! { delegate double ended; } -/// Created with the method [`lines`]. +/// An iterator over the lines of a string, as string slices. +/// +/// This struct is created with the [`lines`] method on [`str`]. +/// See its documentation for more. /// /// [`lines`]: ../../std/primitive.str.html#method.lines +/// [`str`]: ../../std/primitive.str.html #[stable(feature = "rust1", since = "1.0.0")] #[derive(Clone, Debug)] pub struct Lines<'a>(Map, LinesAnyMap>); diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 743e3c41170a3..ae47e6fdfa928 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -15,27 +15,37 @@ //! types. //! //! This module defines atomic versions of a select number of primitive -//! types, including `AtomicBool`, `AtomicIsize`, and `AtomicUsize`. +//! types, including [`AtomicBool`], [`AtomicIsize`], and [`AtomicUsize`]. //! Atomic types present operations that, when used correctly, synchronize //! updates between threads. //! -//! Each method takes an `Ordering` which represents the strength of +//! [`AtomicBool`]: struct.AtomicBool.html +//! [`AtomicIsize`]: struct.AtomicIsize.html +//! [`AtomicUsize`]: struct.AtomicUsize.html +//! +//! Each method takes an [`Ordering`] which represents the strength of //! the memory barrier for that operation. These orderings are the //! same as [LLVM atomic orderings][1]. For more information see the [nomicon][2]. //! +//! [`Ordering`]: enum.Ordering.html +//! //! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations //! [2]: ../../../nomicon/atomics.html //! -//! Atomic variables are safe to share between threads (they implement `Sync`) +//! Atomic variables are safe to share between threads (they implement [`Sync`]) //! but they do not themselves provide the mechanism for sharing and follow the //! [threading model](../../../std/thread/index.html#the-threading-model) of rust. -//! The most common way to share an atomic variable is to put it into an `Arc` (an +//! The most common way to share an atomic variable is to put it into an [`Arc`][arc] (an //! atomically-reference-counted shared pointer). //! +//! [`Sync`]: ../../marker/trait.Sync.html +//! [arc]: ../../../std/sync/struct.Arc.html +//! //! Most atomic types may be stored in static variables, initialized using -//! the provided static initializers like `ATOMIC_BOOL_INIT`. Atomic statics +//! the provided static initializers like [`ATOMIC_BOOL_INIT`]. Atomic statics //! are often used for lazy global initialization. //! +//! [`ATOMIC_BOOL_INIT`]: constant.ATOMIC_BOOL_INIT.html //! //! # Examples //! @@ -148,22 +158,32 @@ unsafe impl Sync for AtomicPtr {} #[stable(feature = "rust1", since = "1.0.0")] #[derive(Copy, Clone, Debug)] pub enum Ordering { - /// No ordering constraints, only atomic operations. Corresponds to LLVM's - /// `Monotonic` ordering. + /// No ordering constraints, only atomic operations. + /// + /// Corresponds to LLVM's [`Monotonic`] ordering. + /// + /// [`Monotonic`]: http://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Relaxed, /// When coupled with a store, all previous writes become visible - /// to the other threads that perform a load with `Acquire` ordering + /// to the other threads that perform a load with [`Acquire`] ordering /// on the same value. + /// + /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire #[stable(feature = "rust1", since = "1.0.0")] Release, /// When coupled with a load, all subsequent loads will see data - /// written before a store with `Release` ordering on the same value + /// written before a store with [`Release`] ordering on the same value /// in other threads. + /// + /// [`Release`]: http://llvm.org/docs/Atomics.html#release #[stable(feature = "rust1", since = "1.0.0")] Acquire, - /// When coupled with a load, uses `Acquire` ordering, and with a store - /// `Release` ordering. + /// When coupled with a load, uses [`Acquire`] ordering, and with a store + /// [`Release`] ordering. + /// + /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire + /// [`Release`]: http://llvm.org/docs/Atomics.html#release #[stable(feature = "rust1", since = "1.0.0")] AcqRel, /// Like `AcqRel` with the additional guarantee that all threads see all @@ -176,7 +196,9 @@ pub enum Ordering { __Nonexhaustive, } -/// An `AtomicBool` initialized to `false`. +/// An [`AtomicBool`] initialized to `false`. +/// +/// [`AtomicBool`]: struct.AtomicBool.html #[cfg(target_has_atomic = "8")] #[stable(feature = "rust1", since = "1.0.0")] pub const ATOMIC_BOOL_INIT: AtomicBool = AtomicBool::new(false); @@ -250,7 +272,7 @@ impl AtomicBool { /// /// [`Ordering`]: enum.Ordering.html /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.Release + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel /// /// # Examples /// @@ -287,7 +309,10 @@ impl AtomicBool { /// /// # Panics /// - /// Panics if `order` is `Acquire` or `AcqRel`. + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. + /// + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, val: bool, order: Ordering) { @@ -404,7 +429,7 @@ impl AtomicBool { /// Stores a value into the `bool` if the current value is the same as the `current` value. /// - /// Unlike `compare_exchange`, this function is allowed to spuriously fail even when the + /// Unlike [`compare_exchange`], this function is allowed to spuriously fail even when the /// comparison succeeds, which can result in more efficient code on some platforms. The /// return value is a result indicating whether the new value was written and containing the /// previous value. @@ -415,6 +440,7 @@ impl AtomicBool { /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or /// weaker than the success ordering. /// + /// [`compare_exchange`]: #method.compare_exchange /// [`Ordering`]: enum.Ordering.html /// [`Release`]: enum.Ordering.html#variant.Release /// [`AcqRel`]: enum.Ordering.html#variant.Release @@ -694,7 +720,10 @@ impl AtomicPtr { /// /// # Panics /// - /// Panics if `order` is `Acquire` or `AcqRel`. + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. + /// + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, ptr: *mut T, order: Ordering) { @@ -1008,7 +1037,10 @@ macro_rules! atomic_int { /// /// # Panics /// - /// Panics if `order` is `Acquire` or `AcqRel`. + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. + /// + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel #[inline] #[$stable] pub fn store(&self, val: $int_type, order: Ordering) { diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs index 89bd3be08519c..ec38345030fa5 100644 --- a/src/libcoretest/slice.rs +++ b/src/libcoretest/slice.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use core::cmp::Ordering::{Equal, Greater, Less}; use core::slice::heapsort; use core::result::Result::{Ok, Err}; use rand::{Rng, XorShiftRng}; @@ -268,6 +269,17 @@ fn sort_unstable() { } } + // Sort using a completely random comparison function. + // This will reorder the elements *somehow*, but won't panic. + for i in 0..v.len() { + v[i] = i as i32; + } + v.sort_unstable_by(|_, _| *rng.choose(&[Less, Equal, Greater]).unwrap()); + v.sort_unstable(); + for i in 0..v.len() { + assert_eq!(v[i], i as i32); + } + // Should not panic. [0i32; 0].sort_unstable(); [(); 10].sort_unstable(); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 05dbbc0987025..8d759d89135ac 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -196,10 +196,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { id: LintId::of(SUPER_OR_SELF_IN_GLOBAL_PATH), reference: "issue #36888 ", }, - FutureIncompatibleInfo { - id: LintId::of(OVERLAPPING_INHERENT_IMPLS), - reference: "issue #36889 ", - }, FutureIncompatibleInfo { id: LintId::of(ILLEGAL_FLOATING_POINT_CONSTANT_PATTERN), reference: "issue #36890 ", @@ -263,4 +259,5 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { store.register_removed("drop_with_repr_extern", "drop flags have been removed"); store.register_removed("transmute_from_fn_item_types", "always cast functions before transmuting them"); + store.register_removed("overlapping_inherent_impls", "converted into hard error, see #36889"); } diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 3a39df505eb07..dc4bd7733fc21 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -322,4 +322,3 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> { } } } - diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index bd6129eb5bee3..fb951fd20e564 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -4212,4 +4212,5 @@ register_diagnostics! { // but `{}` was found in the type `{}` E0567, // auto traits can not have type parameters E0568, // auto-traits can not have predicates, + E0592, // duplicate definitions with name `{}` } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 5b628d51d1513..8ebc5c0a8fe2d 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -145,6 +145,18 @@ //! # } //! ``` //! +//! Note that you cannot use the `?` operator in functions that do not return +//! a `Result` (e.g. `main`). Instead, you can call `.unwrap()` or `match` +//! on the return value to catch any possible errors: +//! +//! ``` +//! use std::io; +//! +//! let mut input = String::new(); +//! +//! io::stdin().read_line(&mut input).unwrap(); +//! ``` +//! //! And a very common source of output is standard output: //! //! ``` diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index c738dc9440614..5b2053e929a10 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -183,9 +183,9 @@ mod prim_unit { } /// Working with raw pointers in Rust is uncommon, /// typically limited to a few patterns. /// -/// Use the `null` function to create null pointers, and the `is_null` method +/// Use the [`null`] function to create null pointers, and the [`is_null`] method /// of the `*const T` type to check for null. The `*const T` type also defines -/// the `offset` method, for pointer math. +/// the [`offset`] method, for pointer math. /// /// # Common ways to create raw pointers /// @@ -213,7 +213,7 @@ mod prim_unit { } /// /// ## 2. Consume a box (`Box`). /// -/// The `into_raw` function consumes a box and returns +/// The [`into_raw`] function consumes a box and returns /// the raw pointer. It doesn't destroy `T` or deallocate any memory. /// /// ``` @@ -227,7 +227,7 @@ mod prim_unit { } /// } /// ``` /// -/// Note that here the call to `drop` is for clarity - it indicates +/// Note that here the call to [`drop`] is for clarity - it indicates /// that we are done with the given value and it should be destroyed. /// /// ## 3. Get it from C. @@ -255,6 +255,11 @@ mod prim_unit { } /// /// *[See also the `std::ptr` module](ptr/index.html).* /// +/// [`null`]: ../std/ptr/fn.null.html +/// [`is_null`]: ../std/primitive.pointer.html#method.is_null +/// [`offset`]: ../std/primitive.pointer.html#method.offset +/// [`into_raw`]: ../std/boxed/struct.Box.html#method.into_raw +/// [`drop`]: ../std/mem/fn.drop.html #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer { } diff --git a/src/libstd_unicode/u_str.rs b/src/libstd_unicode/u_str.rs index 3c02ea82d2a11..770b67acd49ef 100644 --- a/src/libstd_unicode/u_str.rs +++ b/src/libstd_unicode/u_str.rs @@ -19,6 +19,12 @@ use core::str::Split; /// An iterator over the non-whitespace substrings of a string, /// separated by any amount of whitespace. +/// +/// This struct is created by the [`split_whitespace`] method on [`str`]. +/// See its documentation for more. +/// +/// [`split_whitespace`]: ../../std/primitive.str.html#method.split_whitespace +/// [`str`]: ../../std/primitive.str.html #[stable(feature = "split_whitespace", since = "1.1.0")] pub struct SplitWhitespace<'a> { inner: Filter bool>, fn(&&str) -> bool>, diff --git a/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs b/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs index 08e8605e91773..158d3606104a9 100644 --- a/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs +++ b/src/test/compile-fail/coherence-overlapping-inherent-impl-trait.rs @@ -9,10 +9,8 @@ // except according to those terms. #![allow(dead_code)] -#![deny(overlapping_inherent_impls)] trait C {} impl C { fn f() {} } //~ ERROR duplicate definitions with name `f` -//~^ WARN: this was previously accepted impl C { fn f() {} } fn main() { } diff --git a/src/test/compile-fail/inherent-overlap.rs b/src/test/compile-fail/inherent-overlap.rs index 00d41244639f5..18e77ddfd2c5b 100644 --- a/src/test/compile-fail/inherent-overlap.rs +++ b/src/test/compile-fail/inherent-overlap.rs @@ -17,7 +17,6 @@ struct Foo; impl Foo { fn id() {} //~ ERROR duplicate definitions - //~^ WARN previously accepted } impl Foo { @@ -28,7 +27,6 @@ struct Bar(T); impl Bar { fn bar(&self) {} //~ ERROR duplicate definitions - //~^ WARN previously accepted } impl Bar { @@ -39,7 +37,6 @@ struct Baz(T); impl Baz { fn baz(&self) {} //~ ERROR duplicate definitions - //~^ WARN previously accepted } impl Baz> {