| Age | Commit message (Collapse) | Author | Lines |
|
fix silent overflows on `Step` impls
Part of https://github.com/rust-lang/rust/issues/36110
r? @eddyb
|
|
Rollup of 24 pull requests
- Successful merges: #37255, #37317, #37408, #37410, #37422, #37427, #37470, #37501, #37537, #37556, #37557, #37564, #37565, #37566, #37569, #37574, #37577, #37579, #37583, #37585, #37586, #37587, #37589, #37596
- Failed merges: #37521, #37547
|
|
Peekable::peek(): Use Option::as_ref()
Replace the match expression in .peek() with Option::as_ref() since it's the same functionality.
|
|
Add impls for `&Wrapping`. Also `Sum`, `Product` impls for both `Wrapping` and `&Wrapping`.
There are two changes here (split into two commits):
- Ops for references to `&Wrapping` (`Add`, `Sub`, `Mul` etc.) similar to the way they are implemented for primitives.
- Impls for `iter::{Sum,Product}` for `Wrapping`.
As far as I know `impl` stability attributes don't really matter so I didn't bother breaking up the macro for two different kinds of stability. Happy to change if it does matter.
|
|
Add Iterator trait TrustedLen to enable better FromIterator / Extend
This trait attempts to improve FromIterator / Extend code by enabling it to trust the iterator to produce an exact number of elements, which means that reallocation needs to happen only once and is moved out of the loop.
`TrustedLen` differs from `ExactSizeIterator` in that it attempts to include _more_ iterators by allowing for the case that the iterator's len does not fit in `usize`. Consumers must check for this case (for example they could panic, since they can't allocate a collection of that size).
For example, chain can be TrustedLen and all numerical ranges can be TrustedLen. All they need to do is to report an exact size if it fits in `usize`, and `None` as the upper bound otherwise.
The trait describes its contract like this:
```
An iterator that reports an accurate length using size_hint.
The iterator reports a size hint where it is either exact
(lower bound is equal to upper bound), or the upper bound is `None`.
The upper bound must only be `None` if the actual iterator length is
larger than `usize::MAX`.
The iterator must produce exactly the number of elements it reported.
This trait must only be implemented when the contract is upheld.
Consumers of this trait must inspect `.size_hint()`’s upper bound.
```
Fixes #37232
|
|
|
|
|
|
Implement Iterator::fold for .chain(), .cloned(), .map() and the VecDeque iterators.
Chain can do something interesting here where it passes on the fold
into its inner iterators.
The lets the underlying iterator's custom fold() be used, and skips the
regular chain logic in next.
Also implement .fold() specifically for .map() and .cloned() so that any
inner fold improvements are available through map and cloned.
The same way, a VecDeque iterator fold can be turned into two slice folds.
These changes lend the power of the slice iterator's loop codegen to
VecDeque, and to chains of slice iterators, and so on.
It's an improvement for .sum() and .product(), and other uses of fold.
|
|
Chain can do something interesting here where it passes on the fold
into its inner iterators.
The lets the underlying iterator's custom fold() be used, and skips the
regular chain logic in next.
|
|
Implement .fold() specifically for .map() and .cloned() so that any
inner fold improvements are available through map and cloned.
|
|
|
|
|
|
|
|
|
|
|
|
Implement .zip() specialization for Map and Cloned.
The crucial thing for transparent specialization is that we want to
preserve the potential side effects.
The simplest example is that in this code snippet:
`(0..6).map(f).zip((0..4).map(g)).count()`
`f` will be called five times, and `g` four times. The last time for `f`
is when the other iterator is at its end, so this element is unused.
This side effect can be preserved without disturbing code generation for
simple uses of `.map()`.
The `Zip::next_back()` case is even more complicated, unfortunately.
|
|
|
|
|
|
These are displayed by rustdoc so should be correct.
|
|
remove ExactSizeIterator from RangeInclusive<{u,i}{32,size}>
Fixes #36386.
This is a [breaking-change] for nightly users of `#![feature(inclusive_range_syntax)]` and/or `#![feature(inclusive_range)]`.
|
|
Remove data structure specialization for .zip() iterator
Go back on half the specialization, the part that changed the Zip
struct's fields themselves depending on the types of the iterators.
Previous PR: #33090
This means that the Zip iterator will always carry two usize fields,
which are sometimes unused. If a whole for loop using a .zip() iterator is
inlined, these are simply removed and have no effect.
The same improvement for Zip of for example slice iterators remain, and
they still optimize well. However, like when the specialization of zip
was merged, the compiler is still very sensistive to the exact context.
For example this code only autovectorizes if the function is used, not
if the code in zip_sum_i32 is inserted inline where it was called:
```rust
fn zip_sum_i32(xs: &[i32], ys: &[i32]) -> i32 {
let mut s = 0;
for (&x, &y) in xs.iter().zip(ys) {
s += x * y;
}
s
}
fn zipdot_i32_default_zip(b: &mut test::Bencher)
{
let xs = vec![1; 1024];
let ys = vec![1; 1024];
b.iter(|| {
zip_sum_i32(&xs, &ys)
})
}
```
Include a test that checks that `Zip<T, U>` is covariant w.r.t. T and U.
Fixes #35727
|
|
Go back on half the specialization, the part that changed the Zip
struct's fields themselves depending on the types of the iterators.
This means that the Zip iterator will always carry two usize fields,
which are unused. If a whole for loop using a .zip() iterator is
inlined, these are simply removed and have no effect.
The same improvement for Zip of for example slice iterators remain, and
they still optimize well. However, like when the specialization of zip
was merged, the compiler is still very sensistive to the exact context.
For example this code only autovectorizes if the function is used, not
if the code in zip_sum_i32 is inserted inline it was called:
```
fn zip_sum_i32(xs: &[i32], ys: &[i32]) -> i32 {
let mut s = 0;
for (&x, &y) in xs.iter().zip(ys) {
s += x * y;
}
s
}
fn zipdot_i32_default_zip(b: &mut test::Bencher)
{
let xs = vec![1; 1024];
let ys = vec![1; 1024];
b.iter(|| {
zip_sum_i32(&xs, &ys)
})
}
```
Include a test that checks that Zip<T, U> is covariant w.r.t. T and U.
|
|
|
|
|
|
|
|
r? @eddyb
|
|
Introduce max_by/min_by on iterators
See https://github.com/rust-lang/rfcs/issues/1722 for reference.
It seems that there is `min`, `max` (simple computation of min/max), `min_by_key`, `max_by_key` (min/max by comparing mapped values) but no `min_by` and `max_by` (min/max according to comparison function). However, e.g. on vectors or slices there is `sort`, `sort_by_key` and `sort_by`.
|
|
|
|
PR #35695 for `Range` was approved, so it seems that this side-effect-free style is preferred for Range* examples. This PR performs the same translation for `RangeFrom` and `RangeInclusive`. It also removes what looks to be an erroneously commented line for `#![feature(step_by)]`, and an unnecessary primitive-type annotation in `0u8..`.
add `fn main` wrappers to enable Rust Playground "Run" button
|
|
|
|
Implement 1581 (FusedIterator)
* [ ] Implement on patterns. See https://github.com/rust-lang/rust/issues/27721#issuecomment-239638642.
* [ ] Handle OS Iterators. A bunch of iterators (`Args`, `Env`, etc.) in libstd wrap platform specific iterators. The current ones all appear to be well-behaved but can we assume that future ones will be?
* [ ] Does someone want to audit this? On first glance, all of the iterators on which I implemented `FusedIterator` appear to be well-behaved but there are a *lot* of them so a second pair of eyes would be nice.
* I haven't touched rustc internal iterators (or the internal rand) because rustc doesn't actually call `fuse()`.
* `FusedIterator` can't be implemented on `std::io::{Bytes, Chars}`.
Closes: #35602 (Tracking Issue)
Implements: rust-lang/rfcs#1581
|
|
|
|
|
|
Stabilized
* `Cell::as_ptr`
* `RefCell::as_ptr`
* `IpAddr::is_{unspecified,loopback,multicast}`
* `Ipv6Addr::octets`
* `LinkedList::contains`
* `VecDeque::contains`
* `ExitStatusExt::from_raw` - both on Unix and Windows
* `Receiver::recv_timeout`
* `RecvTimeoutError`
* `BinaryHeap::peek_mut`
* `PeekMut`
* `iter::Product`
* `iter::Sum`
* `OccupiedEntry::remove_entry`
* `VacantEntry::into_key`
Deprecated
* `Cell::as_unsafe_cell`
* `RefCell::as_unsafe_cell`
* `OccupiedEntry::remove_pair`
Closes #27708
cc #27709
Closes #32313
Closes #32630
Closes #32713
Closes #34029
Closes #34392
Closes #34285
Closes #34529
|
|
This trait can be used to avoid the overhead of a fuse wrapper when an iterator
is already well-behaved.
Conforming to: RFC 1581
Closes: #35602
|
|
|
|
I'm only making this change in one place so that people can express
their preferences for this stylistic change. If/when this change is
approved I'll go ahead and translate the rest of the `std::ops`
examples.
|
|
|
|
document DoubleEndedIterator::next_back
document DoubleEndedIterator::next_back
fixes #34726
|
|
Add `is_empty` function to `ExactSizeIterator`
All other types implementing a `len` functions have `is_empty` already.
|
|
|
|
This primarily removes a lot of `sync::Static*` APIs and rejiggers the
associated implementations. While doing this it was discovered that the
`is_poisoned` method can actually result in a data race for the Mutex/RwLock
primitives, so the inner `Cell<bool>` was changed to an `AtomicBool` to prevent
the associated data race. Otherwise the usage/gurantees should be the same
they were before.
|
|
fixes #34726
|
|
Improve DoubleEndedIterator examples
Fixes #34065.
r? @steveklabnik
|
|
doc: some `peek` improvements
|
|
|
|
Although the set of APIs being stabilized this release is relatively small, the
trains keep going! Listed below are the APIs in the standard library which have
either transitioned from unstable to stable or those from unstable to
deprecated.
Stable
* `BTreeMap::{append, split_off}`
* `BTreeSet::{append, split_off}`
* `Cell::get_mut`
* `RefCell::get_mut`
* `BinaryHeap::append`
* `{f32, f64}::{to_degrees, to_radians}` - libcore stabilizations mirroring past
libstd stabilizations
* `Iterator::sum`
* `Iterator::product`
Deprecated
* `{f32, f64}::next_after`
* `{f32, f64}::integer_decode`
* `{f32, f64}::ldexp`
* `{f32, f64}::frexp`
* `num::One`
* `num::Zero`
Added APIs (all unstable)
* `iter::Sum`
* `iter::Product`
* `iter::Step` - a few methods were added to accomodate deprecation of One/Zero
Removed APIs
* `From<Range<T>> for RangeInclusive<T>` - everything about `RangeInclusive` is
unstable
Closes #27739
Closes #27752
Closes #32526
Closes #33444
Closes #34152
cc #34529 (new tracking issue)
|
|
Remove unzip() SizeHint hack
This was using an invalid iterator so is likely to end with buggy
behaviour.
It also doesn't even benefit many type in std including Vec so removing it
shouldn't cause any problems.
Fixes: #33468
|
|
|
|
All other types implementing a `len` functions have `is_empty` already.
|