diff options
| author | bors <bors@rust-lang.org> | 2019-08-20 15:01:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-08-20 15:01:24 +0000 |
| commit | 5a56e05abd34e1936df74625c1f40cb6fee0cd4a (patch) | |
| tree | 33d5f0b1aec0faad29a18e8d9e40271486d8c59d /src/libcore | |
| parent | 51879c3abaedb926739095d19a2af638ee6a07d8 (diff) | |
| parent | 218bcf2e01146eb87afbef608f00c8df1e54b415 (diff) | |
| download | rust-5a56e05abd34e1936df74625c1f40cb6fee0cd4a.tar.gz rust-5a56e05abd34e1936df74625c1f40cb6fee0cd4a.zip | |
Auto merge of #63744 - Centril:rollup-g4l3ra9, r=Centril
Rollup of 7 pull requests Successful merges: - #63216 (avoid unnecessary reservations in std::io::Take::read_to_end) - #63265 (Implement `nth_back` for ChunksExactMut) - #63691 (Fix bug in iter::Chain::size_hint) - #63722 (Don't use stage naming in RUSTFLAGS environment variables) - #63723 (Consolidate sigemptyset workarounds) - #63736 (Restore the rustc_plugin crate in the sysroot) - #63743 (Allow git to merge `Cargo.lock`) Failed merges: r? @ghost
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/iter/adapters/chain.rs | 22 | ||||
| -rw-r--r-- | src/libcore/slice/mod.rs | 16 | ||||
| -rw-r--r-- | src/libcore/tests/iter.rs | 48 | ||||
| -rw-r--r-- | src/libcore/tests/slice.rs | 19 |
4 files changed, 97 insertions, 8 deletions
diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs index 0b9f7f6b609..c9612596b1b 100644 --- a/src/libcore/iter/adapters/chain.rs +++ b/src/libcore/iter/adapters/chain.rs @@ -173,17 +173,23 @@ impl<A, B> Iterator for Chain<A, B> where #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); + match self.state { + ChainState::Both => { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); - let lower = a_lower.saturating_add(b_lower); + let lower = a_lower.saturating_add(b_lower); - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => x.checked_add(y), - _ => None - }; + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None + }; - (lower, upper) + (lower, upper) + } + ChainState::Front => self.a.size_hint(), + ChainState::Back => self.b.size_hint(), + } } } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ce5af13d4ca..bfbbb15c8d4 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -4637,6 +4637,22 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> { Some(tail) } } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option<Self::Item> { + let len = self.len(); + if n >= len { + self.v = &mut []; + None + } else { + let start = (len - 1 - n) * self.chunk_size; + let end = start + self.chunk_size; + let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end); + let (head, nth_back) = temp.split_at_mut(start); + self.v = head; + Some(nth_back) + } + } } #[stable(feature = "chunks_exact", since = "1.31.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index a1a27e1d538..3a4f76852a0 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -153,6 +153,54 @@ fn test_iterator_chain_find() { } #[test] +fn test_iterator_chain_size_hint() { + struct Iter { + is_empty: bool, + } + + impl Iterator for Iter { + type Item = (); + + // alternates between `None` and `Some(())` + fn next(&mut self) -> Option<Self::Item> { + if self.is_empty { + self.is_empty = false; + None + } else { + self.is_empty = true; + Some(()) + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + if self.is_empty { + (0, Some(0)) + } else { + (1, Some(1)) + } + } + } + + impl DoubleEndedIterator for Iter { + fn next_back(&mut self) -> Option<Self::Item> { + self.next() + } + } + + // this chains an iterator of length 0 with an iterator of length 1, + // so after calling `.next()` once, the iterator is empty and the + // state is `ChainState::Back`. `.size_hint()` should now disregard + // the size hint of the left iterator + let mut iter = Iter { is_empty: true }.chain(once(())); + assert_eq!(iter.next(), Some(())); + assert_eq!(iter.size_hint(), (0, Some(0))); + + let mut iter = once(()).chain(Iter { is_empty: true }); + assert_eq!(iter.next_back(), Some(())); + assert_eq!(iter.size_hint(), (0, Some(0))); +} + +#[test] fn test_zip_nth() { let xs = [0, 1, 2, 4, 5]; let ys = [10, 11, 12]; diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 4790152512a..6609bc3135a 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -375,6 +375,25 @@ fn test_chunks_exact_mut_nth() { } #[test] +fn test_chunks_exact_mut_nth_back() { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + let mut c = v.chunks_exact_mut(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); + + let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let mut c2 = v2.chunks_exact_mut(3); + assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]); + assert_eq!(c2.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let mut c3 = v3.chunks_exact_mut(10); + assert_eq!(c3.nth_back(0), None); +} + +#[test] fn test_chunks_exact_mut_last() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; let c = v.chunks_exact_mut(2); |
