about summary refs log tree commit diff
path: root/src/liballoc/collections
AgeCommit message (Collapse)AuthorLines
2019-07-04Rollup merge of #62316 - khuey:efficient_last, r=sfacklerMazdak Farrokhzad-0/+60
When possible without changing semantics, implement Iterator::last in terms of DoubleEndedIterator::next_back for types in liballoc and libcore. Provided that the iterator has finite length and does not trigger user-provided code, this is safe. What follows is a full list of the DoubleEndedIterators in liballoc/libcore and whether this optimization is safe, and if not, why not. src/liballoc/boxed.rs Box: Pass through to avoid defeating optimization of the underlying DoubleIterator implementation. This has no correctness impact. src/liballoc/collections/binary_heap.rs Iter: Pass through to avoid defeating optimizations on slice::Iter IntoIter: Not safe, changes Drop order Drain: Not safe, changes Drop order src/liballoc/collections/btree/map.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Keys: Safe to call next_back, invokes no user defined code. Values: ditto ValuesMut: ditto Range: ditto RangeMut: ditto src/liballoc/collections/btree/set.rs Iter: Safe to call next_back, invokes no user defined code. IntoIter: Not safe, changes Drop order Range: Safe to call next_back, invokes no user defined code. src/liballoc/collections/linked_list.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order src/liballoc/collections/vec_deque.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Drain: ditto src/liballoc/string.rs Drain: Safe because return type is a primitive (char) src/liballoc/vec.rs IntoIter: Not safe, changes Drop order Drain: ditto Splice: ditto src/libcore/ascii.rs EscapeDefault: Safe because return type is a primitive (u8) src/libcore/iter/adapters/chain.rs Chain: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/adapters/flatten.rs FlatMap: Not safe, invokes user defined code (Iterator impl) Flatten: ditto FlattenCompat: ditto src/libcore/iter/adapters/mod.rs Rev: Not safe, invokes user defined code (Iterator impl) Copied: ditto Cloned: Not safe, invokes user defined code (Iterator impl and T::clone) Map: Not safe, invokes user defined code (Iterator impl + closure) Filter: ditto FilterMap: ditto Enumerate: Not safe, invokes user defined code (Iterator impl) Skip: ditto Fuse: ditto Inspect: ditto src/libcore/iter/adapters/zip.rs Zip: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/range.rs ops::Range: Not safe, changes Drop order, but ALREADY HAS SPECIALIZATION ops::RangeInclusive: ditto src/libcore/iter/sources.rs Repeat: Not safe, calling last should iloop. Empty: No point, iterator is at most one item long. Once: ditto OnceWith: ditto src/libcore/option.rs Item: No point, iterator is at most one item long. Iter: ditto IterMut: ditto IntoIter: ditto src/libcore/result.rs Iter: No point, iterator is at most one item long IterMut: ditto IntoIter: ditto src/libcore/slice/mod.rs Split: Not safe, invokes user defined closure SplitMut: ditto RSplit: ditto RSplitMut: ditto Windows: Safe, already has specialization Chunks: ditto ChunksMut: ditto ChunksExact: ditto ChunksExactMut: ditto RChunks: ditto RChunksMut: ditto RChunksExact: ditto RChunksExactMut: ditto src/libcore/str/mod.rs Chars: Safe, already has specialization CharIndices: ditto Bytes: ditto Lines: Safe to call next_back, invokes no user defined code. LinesAny: Deprecated Everything that is generic over P: Pattern: Not safe because Pattern invokes user defined code. SplitWhitespace: Safe to call next_back, invokes no user defined code. SplitAsciiWhitespace: ditto This is attempt 2 of #60130. r? @sfackler
2019-07-02When possible without changing semantics, implement Iterator::last in terms ↵Kyle Huey-0/+60
of DoubleEndedIterator::next_back for types in liballoc and libcore. Provided that the iterator has finite length and does not trigger user-provided code, this is safe. What follows is a full list of the DoubleEndedIterators in liballoc/libcore and whether this optimization is safe, and if not, why not. src/liballoc/boxed.rs Box: Pass through to avoid defeating optimization of the underlying DoubleIterator implementation. This has no correctness impact. src/liballoc/collections/binary_heap.rs Iter: Pass through to avoid defeating optimizations on slice::Iter IntoIter: Not safe, changes Drop order Drain: Not safe, changes Drop order src/liballoc/collections/btree/map.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Keys: Safe to call next_back, invokes no user defined code. Values: ditto ValuesMut: ditto Range: ditto RangeMut: ditto src/liballoc/collections/btree/set.rs Iter: Safe to call next_back, invokes no user defined code. IntoIter: Not safe, changes Drop order Range: Safe to call next_back, invokes no user defined code. src/liballoc/collections/linked_list.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order src/liballoc/collections/vec_deque.rs Iter: Safe to call next_back, invokes no user defined code. IterMut: ditto IntoIter: Not safe, changes Drop order Drain: ditto src/liballoc/string.rs Drain: Safe because return type is a primitive (char) src/liballoc/vec.rs IntoIter: Not safe, changes Drop order Drain: ditto Splice: ditto src/libcore/ascii.rs EscapeDefault: Safe because return type is a primitive (u8) src/libcore/iter/adapters/chain.rs Chain: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/adapters/flatten.rs FlatMap: Not safe, invokes user defined code (Iterator impl) Flatten: ditto FlattenCompat: ditto src/libcore/iter/adapters/mod.rs Rev: Not safe, invokes user defined code (Iterator impl) Copied: ditto Cloned: Not safe, invokes user defined code (Iterator impl and T::clone) Map: Not safe, invokes user defined code (Iterator impl + closure) Filter: ditto FilterMap: ditto Enumerate: Not safe, invokes user defined code (Iterator impl) Skip: ditto Fuse: ditto Inspect: ditto src/libcore/iter/adapters/zip.rs Zip: Not safe, invokes user defined code (Iterator impl) src/libcore/iter/range.rs ops::Range: Not safe, changes Drop order, but ALREADY HAS SPECIALIZATION ops::RangeInclusive: ditto src/libcore/iter/sources.rs Repeat: Not safe, calling last should iloop. Empty: No point, iterator is at most one item long. Once: ditto OnceWith: ditto src/libcore/option.rs Item: No point, iterator is at most one item long. Iter: ditto IterMut: ditto IntoIter: ditto src/libcore/result.rs Iter: No point, iterator is at most one item long IterMut: ditto IntoIter: ditto src/libcore/slice/mod.rs Split: Not safe, invokes user defined closure SplitMut: ditto RSplit: ditto RSplitMut: ditto Windows: Safe, already has specialization Chunks: ditto ChunksMut: ditto ChunksExact: ditto ChunksExactMut: ditto RChunks: ditto RChunksMut: ditto RChunksExact: ditto RChunksExactMut: ditto src/libcore/str/mod.rs Chars: Safe, already has specialization CharIndices: ditto Bytes: ditto Lines: Safe to call next_back, invokes no user defined code. LinesAny: Deprecated Everything that is generic over P: Pattern: Not safe because Pattern invokes user defined code. SplitWhitespace: Safe to call next_back, invokes no user defined code. SplitAsciiWhitespace: ditto
2019-07-01Convert more usages overChris Gregory-3/+3
2019-06-11Remove the questionably-useful exampleScott McMurray-22/+0
2019-06-08Add hyperlinks to Vec and VecDequeScott McMurray-2/+2
Let's try the auto-linking instead, since the relative ones don't work.
2019-06-08Apply suggestions from code reviewscottmcm-1/+1
Co-Authored-By: Joe ST <joe@fbstj.net>
2019-06-08Put the docs on the methods instead of the implsScott McMurray-53/+53
Since simulacrum suggested (on Discord) they're better there.
2019-06-08Apply suggestions from code reviewscottmcm-10/+10
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
2019-06-08Add some Vec <-> VecDeque documentationScott McMurray-0/+53
These are more than just `.into_iter().collect()`, so talk about some of their nuances.
2019-05-22Revert "Add implementations of last in terms of next_back on a bunch of ↵Steven Fackler-70/+0
DoubleEndedIterators." This reverts commit 3e86cf36b5114f201868bf459934fe346a76a2d4.
2019-05-20Rollup merge of #60952 - dtolnay:heap, r=AmanieuMazdak Farrokhzad-0/+43
Document BinaryHeap time complexity I went into some detail on the time complexity of `push` because it is relevant for using BinaryHeap efficiently -- specifically that you should avoid pushing many elements in ascending order when possible. r? @Amanieu Closes #47976. Closes #59698.
2019-05-18Document BinaryHeap time complexityDavid Tolnay-0/+43
I went into some detail on the time complexity of `push` because it is relevant for using BinaryHeap efficiently -- specifically that you should avoid pushing many elements in ascending order when possible.
2019-05-19Rollup merge of #60678 - DutchGhost:master, r=scottmcmMazdak Farrokhzad-6/+2
Stabilize vecdeque_rotate This PR stabilizes the vecdeque_rotate feature. r? @scottmcm Closes https://github.com/rust-lang/rust/issues/56686
2019-05-14Rollup merge of #60130 - khuey:efficient_last, r=sfacklerMazdak Farrokhzad-0/+70
Add implementations of last in terms of next_back on a bunch of DoubleEndedIterators Provided a `DoubleEndedIterator` has finite length, `Iterator::last` is equivalent to `DoubleEndedIterator::next_back`. But searching forwards through the iterator when it's unnecessary is obviously not good for performance. I ran into this on one of the collection iterators. I tried adding appropriate overloads for a bunch of the iterator adapters like filter, map, etc, but I ran into a lot of type inference failures after doing so. The other interesting case is what to do with `Repeat`. Do we consider it part of the contract that `Iterator::last` will loop forever on it? The docs do say that the iterator will be evaluated until it returns None. This is also relevant for the adapters, it's trivially easy to observe whether a `Map` adapter invoked its closure a zillion times or just once for the last element.
2019-05-12Auto merge of #60396 - cuviper:ordered-retain, r=scottmcmbors-2/+16
Document the order of {Vec,VecDeque,String}::retain It's natural for `retain` to work in order from beginning to end, but this wasn't actually documented to be the case. If we actually promise this, then the caller can do useful things like track the index of each element being tested, as [discussed in the forum][1]. This is now documented for `Vec`, `VecDeque`, and `String`. [1]: https://users.rust-lang.org/t/vec-retain-by-index/27697 `HashMap` and `HashSet` also have `retain`, and the `hashbrown` implementation does happen to use a plain `iter()` order too, but it's not certain that this should always be the case for these types. r? @scottmcm
2019-05-10Add examples of ordered retainJosh Stone-0/+14
2019-05-09supposed to be 1.36.0Dodo-2/+2
2019-05-09make vecdeque_rotate stableDodo-6/+2
2019-05-01BinaryHeap: add min-heap exampleAlexey Shmalko-0/+24
2019-04-29Document the order of {Vec,VecDeque,String}::retainJosh Stone-2/+2
It's natural for `retain` to work in order from beginning to end, but this wasn't actually documented to be the case. If we actually promise this, then the caller can do useful things like track the index of each element being tested, as [discussed in the forum][1]. This is now documented for `Vec`, `VecDeque`, and `String`. [1]: https://users.rust-lang.org/t/vec-retain-by-index/27697 `HashMap` and `HashSet` also have `retain`, and the `hashbrown` implementation does happen to use a plain `iter()` order too, but it's not certain that this should always be the case for these types.
2019-04-26Use "capacity" as parameter name in with_capacity() methodsMatthias Geier-4/+4
Closes #60271.
2019-04-25ignore-tidy-filelength on all files with greater than 3000 linesvarkor-0/+2
2019-04-19Add implementations of last in terms of next_back on a bunch of ↵Kyle Huey-0/+70
DoubleEndedIterators. r?Manishearth
2019-04-19Auto merge of #60072 - RalfJung:linked-list, r=shepmasterbors-11/+37
fix LinkedList invalidating mutable references The test `test_insert_prev` failed in Miri due to what I consider a bug in `LinkedList`: in various places, `NonNull::as_mut` got called to modify the `prev`/`next` pointers of existing nodes. In particular, the unstable `insert_next` has to modify the `next` pointer of the node that was last handed out by the iterator; to this end it creates a mutable reference to the *entire node* that overlaps with the mutable reference to the node's content that was handed out by the iterator! Thus, the next use if said mutable reference is UB. In code: ```rust loop { match it.next() { // mutable reference handed to us None => break, Some(elt) => { it.insert_next(*elt + 1); // this invalidates `elt` because it creates an overlapping mutable reference match it.peek_next() { Some(x) => assert_eq!(*x, *elt + 2), // this use of `elt` now is a use of an invalid pointer None => assert_eq!(8, *elt), } } } } ``` This PR fixes that by using `as_ptr` instead of `as_mut`. This avoids invalidating the mutable reference that was handed to the user. I did this in all methods called by iterators, just to be sure. Cc @Gankro
2019-04-19fix LinkedList invalidating mutable referencesRalf Jung-11/+37
2019-04-19move variable down to where it is usedRalf Jung-5/+5
2019-04-18make liballoc internal test suite mostly pass in MiriRalf Jung-1/+12
2019-04-05Use for_each to extend collectionsJosh Stone-13/+7
This updates the `Extend` implementations to use `for_each` for many collections: `BinaryHeap`, `BTreeMap`, `BTreeSet`, `LinkedList`, `Path`, `TokenStream`, `VecDeque`, and `Wtf8Buf`. Folding with `for_each` enables better performance than a `for`-loop for some iterators, especially if they can just forward to internal iterators, like `Chain` and `FlatMap` do.
2019-03-29improve worst-case performance of BTreeSet difference and intersectionStein Somers-65/+233
2019-03-26adjust MaybeUninit API to discussionsRalf Jung-5/+5
uninitialized -> uninit into_initialized -> assume_init read_initialized -> read set -> write
2019-02-25Rollup merge of #58421 - nox:relax-bounds-binary-heap, r=dtolnayMazdak Farrokhzad-244/+244
Relax some Ord bounds on BinaryHeap<T> Notably, iterators don't require any trait bounds to be iterated.
2019-02-22Rollup merge of #58431 - RalfJung:btree, r=Mark-SimulacrumMazdak Farrokhzad-15/+42
fix overlapping references in BTree This fixes two kinds of overlapping references in BTree (both found by running the BTree test suite in Miri). In `into_slices_mut`, we did `k.into_key_slice_mut()` followed by `self.into_val_slice_mut()` (where `k` is a copy of `self`). Calling `into_val_slice_mut` calls `self.len()`, which creates a shared reference to `NodeHeader`, which unfortunately (due to padding) overlaps with the mutable reference returned by `into_key_slice_mut`. Hence the key slice got (partially) invalidated. The fix is to avoid creating an `&NodeHeader` after the first slice got created. In the iterators, we used to first create the references that will be returned, and then perform the walk on the tree. Walking the tree creates references (such as `&mut InternalNode`) that overlap with all of the keys and values stored in a pointer; in particular, they overlap with the references the iterator will later return. This is fixed by reordering the operations of walking the tree and obtaining the inner references. The test suite still passes (and it passes in Miri now!), but there is a lot of code here that I do not understand...
2019-02-22Rollup merge of #58064 - llogiq:vec-deque-try-rfold, r=scottmcmMazdak Farrokhzad-5/+46
override `VecDeque::try_rfold`, also update iterator This keeps the slice based iteration and updates the iterator state after each slice. It also uses a loop to reduce the amount of code. This uses unsafe code, so some thorough review would be appreciated. Cc @RalfJung
2019-02-20Rollup merge of #58553 - scottmcm:more-ihle, r=Centrilkennytm-29/+29
Use more impl header lifetime elision Inspired by seeing explicit lifetimes on these two: - https://doc.rust-lang.org/nightly/std/slice/struct.Iter.html#impl-FusedIterator - https://doc.rust-lang.org/nightly/std/primitive.u32.html#impl-Not And a follow-up to https://github.com/rust-lang/rust/pull/54687, that started using IHLE in libcore. Most of the changes in here fall into two big categories: - Removing lifetimes from common traits that can essentially never user a lifetime from an input (particularly `Drop`, `Debug`, and `Clone`) - Forwarding impls that are only possible because the lifetime doesn't matter (like `impl<R: Read + ?Sized> Read for &mut R`) I omitted things that seemed like they could be more controversial, like the handful of iterators that have a `Item: 'static` despite the iterator having a lifetime or the `PartialEq` implementations [where the flipped one cannot elide the lifetime](https://internals.rust-lang.org/t/impl-type-parameter-aliases/9403/2?u=scottmcm). I also removed two lifetimes that turned out to be completely unused; see https://github.com/rust-lang/rust/issues/41960#issuecomment-464557423
2019-02-18override `VecDeque::try_rfold`, also update iteratorAndre Bogus-5/+46
This keeps the slice based iteration and updates the iterator state after each slice. It also uses a loop to reduce the amount of code. This uses unsafe code, so some thorough review would be appreciated.
2019-02-17Use more impl header lifetime elisionScott McMurray-29/+29
There are two big categories of changes in here - Removing lifetimes from common traits that can essentially never user a lifetime from an input (particularly `Drop` & `Debug`) - Forwarding impls that are only possible because the lifetime doesn't matter (like `impl<R: Read + ?Sized> Read for &mut R`) I omitted things that seemed like they could be more controversial, like the handful of iterators that have a `Item: 'static` despite the iterator having a lifetime or the `PartialEq` implementations where the flipped one cannot elide the lifetime.
2019-02-14split MaybeUninit into several features, expand docs a bitRalf Jung-2/+2
2019-02-13fix invalidating references in BTree iteratorsRalf Jung-13/+21
2019-02-13fix overlapping mutable and shared references in BTreeMap's into_slices_mutRalf Jung-3/+22
2019-02-13Relax some Ord bounds on BinaryHeap<T>Anthony Ramine-244/+244
Notably, iterators don't require any trait bounds to be iterated.
2019-02-10libs: doc commentsAlexander Regueiro-10/+10
2019-02-10tests: doc commentsAlexander Regueiro-5/+5
2019-02-07Rollup merge of #58123 - lnicola:binary-heap-no-bounds-checks, r=sfacklerkennytm-3/+8
Avoid some bounds checks in binary_heap::{PeekMut,Hole} Fixes #58121.
2019-02-03Avoid some bounds checks in binary_heap::{PeekMut,Hole}Laurențiu Nicola-3/+8
2019-02-03liballoc: revert nested imports style changes.Mazdak Farrokhzad-83/+58
2019-02-02liballoc: fix some idiom lints.Mazdak Farrokhzad-58/+58
2019-02-02liballoc: elide some lifetimes.Mazdak Farrokhzad-82/+81
2019-02-02liballoc: apply uniform_paths.Mazdak Farrokhzad-7/+8
2019-02-02liballoc: prefer imports of borrow from libcore.Mazdak Farrokhzad-9/+7
2019-02-02liballoc: refactor & fix some imports.Mazdak Farrokhzad-72/+87