8000 Rollup of 19 pull requests by m-ou-se · Pull Request #81013 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Rollup of 19 pull requests #81013

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

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
64f11b9
Update tests of "unused_lifetimes" lint for async functions and corre…
Dec 4, 2020
3ea744e
Recommend panic::resume_unwind instead of panicking.
frewsxcv Dec 18, 2020
1f9a8a1
Add a `std::io::read_to_string` function
camelid Nov 5, 2020
4ee6d1b
Add description independent of `Read::read_to_string`
camelid Dec 30, 2020
588786a
Add error docs
camelid Dec 30, 2020
7ed824e
Add Iterator::intersperse_with
lukaslueg Dec 31, 2020
7a0ada0
Remove FIXME-notes
lukaslueg Jan 6, 2021
f7d261c
Get rid of `DepConstructor`
jyn514 Jan 8, 2021
ebe402d
Fix handling of malicious Readers in read_to_end
sfackler Jan 11, 2021
a9ef798
clean up control flow
sfackler Jan 11, 2021
5cb8303
make check a bit more clear
sfackler Jan 11, 2021
e6c07b0
clarify docs a bit
sfackler Jan 11, 2021
7463292
Add docs on performance
camelid Jan 12, 2021
16692ab
Suggest `_` and `..` if a pattern has too few fields
8000 camelid Dec 13, 2020
5fe61a7
Simplify code
camelid Dec 19, 2020
f3d9df5
Suggest `Variant(..)` if all of the mentioned fields are `_`
camelid Dec 19, 2020
a5e8e6e
Pluralize 'parenthesis' correctly
camelid Dec 19, 2020
fe82cc3
Specialize `..` help message for all fields vs. the rest
camelid Dec 19, 2020
9959d6d
Only suggest `..` if more than one field is missing
camelid Dec 20, 2020
1bce775
Add a test case with lots of whitespace
camelid Jan 13, 2021
d7307a7
Always show suggestions in their own subwindows
camelid Jan 13, 2021
c3f7429
Use better ICE message when no MIR is available
camelid Jan 13, 2021
7e83fec
remove unstable deprecated Vec::remove_item
KodrAus Jan 13, 2021
6bfd987
Update books
ehuss Jan 13, 2021
e8c8793
Include `..` suggestion if fields are all wildcards
camelid Jan 13, 2021
d65cb6e
deprecate atomic::spin_loop_hint in favour of hint::spin_loop
KodrAus Jan 13, 2021
697b20f
Fixed incorrect doc comment
trevarj Jan 13, 2021
52adfdd
Use Option::map_or instead of `.map(..).unwrap_or(..)`
LingMan Jan 11, 2021
64c1b0d
Fix -Cpasses=list and llvm version print with -vV
bjorn3 Jan 13, 2021
5b1316f
unix ExitStatus: Do not treat WIFSTOPPED as WIFSIGNALED
ijackson Dec 12, 2020
12d62aa
unix ExitStatus: Clarify docs for .signal()
ijackson Dec 12, 2020
530270f
unix ExitStatus: Provide .into_raw()
ijackson Dec 12, 2020
3f05051
unix ExitStatus: Provide .core_dumped
ijackson Dec 12, 2020
f060b9e
unix ExitStatus: Provide .stopped_signal()
ijackson Dec 12, 2020
42ea8f6
unix ExitStatus: Provide .continued()
ijackson Dec 12, 2020
29c851a
Replace `Ie` with `In other words`
ijackson Dec 13, 2020
06a405c
Replace `Ie` with `In other words`
ijackson Dec 13, 2020
fa68567
unix ExitStatus: Add tracking issue to new methods
ijackson Jan 4, 2021
7012194
ExitStatusExt unix: Retrospectively seal this trait
ijackson Jan 4, 2021
f3e7199
ExitStatusExt windows: Retrospectively seal this trait
ijackson Jan 4, 2021
efddf59
Fix typo saeled -> sealed
dtolnay Jan 11, 2021
05a88aa
ExitStatusExt: Fix build on Fuchsia
ijackson Jan 13, 2021
b59fa3d
Fix stabilisation version of slice_strip
ijackson Jan 13, 2021
9528988
Add doc intralinks
lukaslueg Jan 13, 2021
0342fd1
Remove the unused context from CreateDebugLocation
cuviper Jan 13, 2021
391b4cc
Fix formatting specifiers doc link
calebsander Jan 13, 2021
9b2f085
Improve Iterator::intersperse_ docs
lukaslueg Jan 13, 2021
eb72dc5
Add as_ref and as_mut methods for Bound
glittershark Dec 28, 2020
a8d0161
Fix typos in Fuchsia unix_process_wait_more
dtolnay Jan 14, 2021
05f5db4
Rollup merge of #79689 - Vooblin:patch1, r=tmandry
m-ou-se Jan 14, 2021
aacb26d
Rollup merge of #79982 - ijackson:exit-status, r=dtolnay
m-ou-se Jan 14, 2021
b07415c
Rollup merge of #80017 - camelid:sugg-rest-pattern, r=estebank
m-ou-se Jan 14, 2021
473c292
Rollup merge of #80169 - frewsxcv:frewsxcv-docs-fix, r=jyn514
m-ou-se Jan 14, 2021
35833c2
Rollup merge of #80217 - camelid:io-read_to_string, r=m-ou-se
m-ou-se Jan 14, 2021
4ac831b
Rollup merge of #80444 - glittershark:bound-as-ref, r=dtolnay
m-ou-se Jan 14, 2021
7c4d34f
Rollup merge of #80567 - lukaslueg:intersperse_with, r=m-ou-se
m-ou-se Jan 14, 2021
4913b50
Rollup merge of #80829 - jyn514:dep-constructor, r=michaelwoerister
m-ou-se Jan 14, 2021
09276b0
Rollup merge of #80895 - sfackler:read-to-end-ub, r=m-ou-se
m-ou-se Jan 14, 2021
c0c379a
Rollup merge of #80944 - LingMan:map_or, r=nagisa
m-ou-se Jan 14, 2021
de47f47
Rollup merge of #80966 - KodrAus:deprecate/spin_loop_hint, r=m-ou-se
m-ou-se Jan 14, 2021
b480d2b
Rollup merge of #80969 - camelid:monomorph-ice-msg, r=nagisa
m-ou-se Jan 14, 2021
b18bbf5
Rollup merge of #80972 - KodrAus:deprecate/remove_item, r=nagisa
m-ou-se Jan 14, 2021
4e5eb81
Rollup merge of #80973 - ehuss:update-books, r=ehuss
m-ou-se Jan 14, 2021
e4f75cc
Rollup merge of #80980 - trevarj:patch-1, r=nagisa
m-ou-se Jan 14, 2021
459b274
Rollup merge of #80981 - bjorn3:bjorn3-patch-1, r=jonas-schievink
m-ou-se Jan 14, 2021
4dc3a44
Rollup merge of #80985 - ijackson:slice-strip-fix, r=jyn514
m-ou-se Jan 14, 2021
896757f
Rollup merge of #80990 - cuviper:unused-debug-context, r=nagisa
m-ou-se Jan 14, 2021
ce19d93
Rollup merge of #80991 - calebsander:fix/fmt-link, r=m-ou-se
m-ou-se Jan 14, 2021
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
Prev Previous commit
Next Next commit
Add Iterator::intersperse_with
  • Loading branch information
lukaslueg committed Dec 31, 2020
commit 7ed824ebd158d24e0c570d0f4bedc3be566b4619
154 changes: 133 additions & 21 deletions library/core/src/iter/adapters/intersperse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,37 +40,149 @@ where
}
}

fn fold<B, F>(mut self, init: B, mut f: F) -> B
fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
let mut accum = init;
let separator = self.separator;
intersperse_fold(self.iter, init, f, move || separator.clone(), self.needs_sep)
}

fn size_hint(&self) -> (usize, Option<usize>) {
intersperse_size_hint(&self.iter, self.needs_sep)
}
}

/// An iterator adapter that places a separator between all elements.
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub struct IntersperseWith<I, G>
where
I: Iterator,
{
separator: G,
iter: Peekable<I>,
needs_sep: bool,
}

// FIXME This manual implementation is needed as #[derive] misplaces trait bounds,
// requiring <I as Iterator>::Item to be Debug on the struct-definition, which is
// not what we want.
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I, G> crate::fmt::Debug for IntersperseWith<I, G>
where
I: Iterator + crate::fmt::Debug,
I::Item: crate::fmt::Debug,
G: crate::fmt::Debug,
{
fn fmt(&self, f: &mut crate::fmt::Formatter<'_>) -> crate::fmt::Result {
f.debug_struct("IntersperseWith")
.field("separator", &self.separator)
.field("iter", &self.iter)
.field("needs_sep", &self.needs_sep)
.finish()
}
}

// Use `peek()` first to avoid calling `next()` on an empty iterator.
if !self.needs_sep || self.iter.peek().is_some() {
if let Some(x) = self.iter.next() {
accum = f(accum, x);
}
// FIXME This manual implementation is needed as #[derive] misplaces trait bounds,
// requiring <I as Iterator>::Item to be Clone on the struct-definition, which is
// not what we want.
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I, G> crate::clone::Clone for IntersperseWith<I, G>
where
I: Iterator + crate::clone::Clone,
I::Item: crate::clone::Clone,
G: Clone,
{
fn clone(&self) -> Self {
IntersperseWith {
separator: self.separator.clone(),
iter: self.iter.clone(),
needs_sep: self.needs_sep.clone(),
}
}
}

let element = &self.separator;
impl<I, G> IntersperseWith<I, G>
where
I: Iterator,
G: FnMut() -> I::Item,
{
pub(in crate::iter) fn new(iter: I, separator: G) -> Self {
Self { iter: iter.peekable(), separator, needs_sep: false }
}
}

self.iter.fold(accum, |mut accum, x| {
accum = f(accum, element.clone());
accum = f(accum, x);
accum
})
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
impl<I, G> Iterator for IntersperseWith<I, G>
where
I: Iterator,
G: FnMut() -> I::Item,
{
type Item = I::Item;

#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.needs_sep && self.iter.peek().is_some() {
self.needs_sep = false;
Some((self.separator)())
} else {
self.needs_sep = true;
self.iter.next()
}
}

fn fold<B, F>(self, init: B, f: F) -> B
where
Self: Sized,
F: FnMut(B, Self::Item) -> B,
{
intersperse_fold(self.iter, init, f, self.separator, self.needs_sep)
}

fn size_hint(&self) -> (usize, Option<usize>) {
let (lo, hi) = self.iter.size_hint();
let next_is_elem = !self.needs_sep;
let lo = lo.saturating_sub(next_is_elem as usize).saturating_add(lo);
let hi = match hi {
Some(hi) => hi.saturating_sub(next_is_elem as usize).checked_add(hi),
None => None,
};
(lo, hi)
intersperse_size_hint(&self.iter, self.needs_sep)
}
}

fn intersperse_size_hint<I>(iter: &I, needs_sep: bool) -> (usize, Option<usize>)
where
I: Iterator,
{
let (lo, hi) = iter.size_hint();
let next_is_elem = !needs_sep;
let lo = lo.saturating_sub(next_is_elem as usize).saturating_add(lo);
let hi = match hi {
Some(hi) => hi.saturating_sub(next_is_elem as usize).checked_add(hi),
None => None,
};
(lo, hi)
}

fn inters 8000 perse_fold<I, B, F, G>(
mut iter: Peekable<I>,
init: B,
mut f: F,
mut separator: G,
needs_sep: bool,
) -> B
where
I: Iterator,
F: FnMut(B, I::Item) -> B,
G: FnMut() -> I::Item,
{
let mut accum = init;

// Use `peek()` first to avoid calling `next()` on an empty iterator.
if !needs_sep || iter.peek().is_some() {
if let Some(x) = iter.next() {
accum = f(accum, x);
}
}

iter.fold(accum, |mut accum, x| {
accum = f(accum, separator());
accum = f(accum, x);
accum
})
}
2 changes: 1 addition & 1 deletion library/core/src/iter/adapters/mod.rs
6D47
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub use self::flatten::Flatten;
pub use self::copied::Copied;

#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::intersperse::Intersperse;
pub use self::intersperse::{Intersperse, IntersperseWith};

#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::map_while::MapWhile;
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,8 +395,6 @@ pub use self::adapters::Cloned;
pub use self::adapters::Copied;
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub use self::adapters::Flatten;
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::adapters::Intersperse;
#[unstable(feature = "iter_map_while", reason = "recently added", issue = "68537")]
pub use self::adapters::MapWhile;
#[unstable(feature = "inplace_iteration", issue = "none")]
Expand All @@ -410,6 +408,8 @@ pub use self::adapters::{
Chain, Cycle, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Rev, Scan,
Skip, SkipWhile, Take, TakeWhile, Zip,
};
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
pub use self::adapters::{Intersperse, IntersperseWith};

pub(crate) use self::adapters::process_results;

Expand Down
27 changes: 26 additions & 1 deletion library/core/src/iter/traits/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::ops::{Add, ControlFlow, Try};
use super::super::TrustedRandomAccess;
use super::super::{Chain, Cloned, Copied, Cycle, Enumerate, Filter, FilterMap, Fuse};
use super::super::{FlatMap, Flatten};
use super::super::{FromIterator, Intersperse, Product, Sum, Zip};
use super::super::{FromIterator, Intersperse, IntersperseWith, Product, Sum, Zip};
use super::super::{
Inspect, Map, MapWhile, Peekable, Rev, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile,
};
Expand Down Expand Up @@ -591,6 +591,31 @@ pub trait Iterator {
Intersperse::new(self, separator)
}

/// Places an element generated by `separator` between all elements.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iter_intersperse)]
///
/// let src = ["Hello", "to", "all", "people"].iter().copied();
/// let mut separator = [" ❤️ ", " 😀 "].iter().copied().cycle();
///
/// let result = src.intersperse_with(|| separator.next().unwrap()).collect::<String>();
/// assert_eq!(result, "Hello ❤️ to 😀 all ❤️ people");
/// ```
#[inline]
#[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")]
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where
Self: Sized,
G: FnMut() -> Self::Item,
{
IntersperseWith::new(self, separator)
}

/// Takes a closure and creates an iterator which calls that closure on each
/// element.
///
Expand Down
30 changes: 30 additions & 0 deletions library/core/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3508,6 +3508,12 @@ pub fn extend_for_unit() {

#[test]
fn test_intersperse() {
let v = std::iter::empty().intersperse(0u32).collect::<Vec<_>>();
assert_eq!(v, vec![]);

let v = std::iter::once(1).intersperse(0).collect::<Vec<_>>();
assert_eq!(v, vec![1]);

let xs = ["a", "", "b", "c"];
let v: Vec<&str> = xs.iter().map(|x| x.clone()).intersperse(", ").collect();
let text: String = v.concat();
Expand All @@ -3520,6 +3526,9 @@ fn test_intersperse() {

#[test]
fn test_intersperse_size_hint() {
let iter = std::iter::empty::<i32>().intersperse(0);
assert_eq!(iter.size_hint(), (0, Some(0)));

let xs = ["a", "", "b", "c"];
let mut iter = xs.iter().map(|x| x.clone()).intersperse(", ");
assert_eq!(iter.size_hint(), (7, Some(7)));
Expand Down Expand Up @@ -3587,3 +3596,24 @@ fn test_try_fold_specialization_intersperse_err() {
iter.try_for_each(|item| if item == "b" { None } else { Some(()) });
assert_eq!(iter.next(), None);
}

#[test]
fn test_intersperse_with() {
#[derive(PartialEq, Debug)]
struct NotClone {
u: u32,
}
let r = vec![NotClone { u: 0 }, NotClone { u: 1 }]
.into_iter()
.intersperse_with(|| NotClone { u: 2 })
.collect::<Vec<_>>();
assert_eq!(r, vec![NotClone { u: 0 }, NotClone { u: 2 }, NotClone { u: 1 }]);

let mut ctr = 100;
let separator = || {
ctr *= 2;
ctr
};
let r = (0..3).intersperse_with(separator).collect::<Vec<_>>();
assert_eq!(r, vec![0, 200, 1, 400, 2]);
}
0