summary refs log tree commit diff
path: root/library/alloc/tests/vec.rs
AgeCommit message (Collapse)AuthorLines
2024-01-26Rollup merge of #119917 - Zalathar:split-off, r=cuviperMatthias Krüger-6/+18
Remove special-case handling of `vec.split_off(0)` #76682 added special handling to `Vec::split_off` for the case where `at == 0`. Instead of copying the vector's contents into a freshly-allocated vector and returning it, the special-case code steals the old vector's allocation, and replaces it with a new (empty) buffer with the same capacity. That eliminates the need to copy the existing elements, but comes at a surprising cost, as seen in #119913. The returned vector's capacity is no longer determined by the size of its contents (as would be expected for a freshly-allocated vector), and instead uses the full capacity of the old vector. In cases where the capacity is large but the size is small, that results in a much larger capacity than would be expected from reading the documentation of `split_off`. This is especially bad when `split_off` is called in a loop (to recycle a buffer), and the returned vectors have a wide variety of lengths. I believe it's better to remove the special-case code, and treat `at == 0` just like any other value: - The current documentation states that `split_off` returns a “newly allocated vector”, which is not actually true in the current implementation when `at == 0`. - If the value of `at` could be non-zero at runtime, then the caller has already agreed to the cost of a full memcpy of the taken elements in the general case. Avoiding that copy would be nice if it were close to free, but the different handling of capacity means that it is not. - If the caller specifically wants to avoid copying in the case where `at == 0`, they can easily implement that behaviour themselves using `mem::replace`. Fixes #119913.
2024-01-21Auto merge of #85528 - the8472:iter-markers, r=dtolnaybors-2/+6
Implement iterator specialization traits on more adapters This adds * `TrustedLen` to `Skip` and `StepBy` * `TrustedRandomAccess` to `Skip` * `InPlaceIterable` and `SourceIter` to `Copied` and `Cloned` The first two might improve performance in the compiler itself since `skip` is used in several places. Constellations that would exercise the last point are probably rare since it would require an owning iterator that has references as Items somewhere in its iterator pipeline. Improvements for `Skip`: ``` # old test iter::bench_skip_trusted_random_access ... bench: 8,335 ns/iter (+/- 90) # new test iter::bench_skip_trusted_random_access ... bench: 2,753 ns/iter (+/- 27) ```
2024-01-13Remove special-case handling of `vec.split_off(0)`Zalathar-6/+18
2024-01-11apply fmtklensy-7/+3
2024-01-10Implement in-place iteratation markers for iter::{Copied, Cloned}The8472-2/+6
2024-01-02Adjust library tests for unused_tuple_struct_fields -> dead_codeJake Goulding-3/+3
2023-12-11Auto merge of #117758 - Urgau:lint_pointer_trait_comparisons, r=davidtwcobors-1/+1
Add lint against ambiguous wide pointer comparisons This PR is the resolution of https://github.com/rust-lang/rust/issues/106447 decided in https://github.com/rust-lang/rust/issues/117717 by T-lang. ## `ambiguous_wide_pointer_comparisons` *warn-by-default* The `ambiguous_wide_pointer_comparisons` lint checks comparison of `*const/*mut ?Sized` as the operands. ### Example ```rust let ab = (A, B); let a = &ab.0 as *const dyn T; let b = &ab.1 as *const dyn T; let _ = a == b; ``` ### Explanation The comparison includes metadata which may not be expected. ------- This PR also drops `clippy::vtable_address_comparisons` which is superseded by this one. ~~One thing: is the current naming right? `invalid` seems a bit too much.~~ Fixes https://github.com/rust-lang/rust/issues/117717
2023-12-10remove redundant importssurechen-2/+0
detects redundant imports that can be eliminated. for #117772 : In order to facilitate review and modification, split the checking code and removing redundant imports code into two PR.
2023-12-06Adjust tests for newly added ambiguous_wide_pointer_comparisons lintUrgau-1/+1
2023-12-05Fix in-place collect not reallocating when necessaryThe 8472-0/+8
2023-11-28Auto merge of #110353 - the8472:in-place-flatten-chunks, r=cuviperbors-2/+43
Expand in-place iteration specialization to Flatten, FlatMap and ArrayChunks This enables the following cases to collect in-place: ```rust let v = vec![[0u8; 4]; 1024] let v: Vec<_> = v.into_iter().flatten().collect(); let v: Vec<Option<NonZeroUsize>> = vec![NonZeroUsize::new(0); 1024]; let v: Vec<_> = v.into_iter().flatten().collect(); let v = vec![u8; 4096]; let v: Vec<_> = v.into_iter().array_chunks::<4>().collect(); ``` Especially the nicheful-option-flattening should be useful in real code.
2023-09-28Auto merge of #111278 - EFanZh:implement-from-array-refs-for-vec, r=dtolnaybors-0/+10
Implement `From<{&,&mut} [T; N]>` for `Vec<T>` where `T: Clone` Currently, if `T` implements `Clone`, we can create a `Vec<T>` from an `&[T]` or an `&mut [T]`, can we also support creating a `Vec<T>` from an `&[T; N]` or an `&mut [T; N]`? Also, do I need to add `#[inline]` to the implementation? ACP: rust-lang/libs-team#220. [Accepted] Closes #100880.
2023-09-03support in-place collecting additional FlatMap shapesThe 8472-0/+11
2023-09-03Expand in-place iteration specialization to Flatten, FlatMap and ArrayChunksThe 8472-2/+32
2023-08-23Bump cfg(bootstrap)Mark Rousskov-1/+0
2023-07-16Implement `From<{&,&mut} [T; N]>` for `Vec<T>`EFanZh-0/+10
2023-07-14Auto merge of #113113 - Amanieu:box-vec-zst, r=Mark-Simulacrumbors-0/+65
Eliminate ZST allocations in `Box` and `Vec` This PR fixes 2 issues with `Box` and `RawVec` related to ZST allocations. Specifically, the `Allocator` trait requires that: - If you allocate a zero-sized layout then you must later deallocate it, otherwise the allocator may leak memory. - You cannot pass a ZST pointer to the allocator that you haven't previously allocated. These restrictions exist because an allocator implementation is allowed to allocate non-zero amounts of memory for a zero-sized allocation. For example, `malloc` in libc does this. Currently, ZSTs are handled differently in `Box` and `Vec`: - `Vec` never allocates when `T` is a ZST or if the vector capacity is 0. - `Box` just blindly passes everything on to the allocator, including ZSTs. This causes problems due to the free conversions between `Box<[T]>` and `Vec<T>`, specifically that ZST allocations could get leaked or a dangling pointer could be passed to `deallocate`. This PR fixes this by changing `Box` to not allocate for zero-sized values and slices. It also fixes a bug in `RawVec::shrink` where shrinking to a size of zero did not actually free the backing memory.
2023-07-13Eliminate ZST allocations in `Box` and `Vec`Amanieu d'Antras-0/+65
2023-07-03enable test_join test in MiriRalf Jung-0/+1
2023-06-14s/drain_filter/extract_if/ for Vec, Btree{Map,Set} and LinkedListThe 8472-22/+22
2023-06-14remove drain-on-drop behavior from vec::DrainFilter and add #[must_use]The 8472-30/+1
2023-06-13ignore core, alloc and test tests that require unwinding on panic=abortPietro Albini-0/+11
2023-04-26Spelling library/Josh Soref-1/+1
* advance * aligned * borrowed * calculate * debugable * debuggable * declarations * desugaring * documentation * enclave * ignorable * initialized * iterator * kaboom * monomorphization * nonexistent * optimizer * panicking * process * reentrant * rustonomicon * the * uninitialized Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2023-03-27replace advance_by returning usize with Result<(), NonZeroUsize>The 8472-9/+10
2023-03-27Change advance(_back)_by to return `usize` instead of `Result<(), usize>`The 8472-10/+11
A successful advance is now signalled by returning `0` and other values now represent the remaining number of steps that couldn't be advanced as opposed to the amount of steps that have been advanced during a partial advance_by. This simplifies adapters a bit, replacing some `match`/`if` with arithmetic. Whether this is beneficial overall depends on whether `advance_by` is mostly used as a building-block for other iterator methods and adapters or whether we also see uses by users where `Result` might be more useful.
2023-01-14Remove various double spaces in source comments.André Vennberg-1/+1
2022-12-24add lib tests for vec::IntoIter alignment issuesRalf Jung-2/+27
2022-11-23Add `#![deny(unsafe_op_in_unsafe_fn)]` in liballoc testsThom Chiovoloni-1/+2
2022-10-04Rollup merge of #101642 - SkiFire13:fix-inplace-collection-leak, r=the8472Dylan DPC-30/+35
Fix in-place collection leak when remaining element destructor panic Fixes #101628 cc `@the8472` I went for the drop guard route, placing it immediately before the `forget_allocation_drop_remaining` call and after the comment, as to signal they are closely related. I also updated the test to check for the leak, though the only change really needed was removing the leak clean up for miri since now that's no longer leaked.
2022-09-10Update testGiacomo Stevanato-33/+34
2022-09-10Adapt inplace collection leak test to check for no leaksGiacomo Stevanato-16/+20
2022-08-31fix into_iter on ZSTRalf Jung-0/+6
2022-08-30Rollup merge of #95376 - WaffleLapkin:drain_keep_rest, r=dtolnayDylan DPC-0/+59
Add `vec::Drain{,Filter}::keep_rest` This PR adds `keep_rest` methods to `vec::Drain` and `vec::DrainFilter` under `drain_keep_rest` feature gate: ```rust // mod alloc::vec impl<T, A: Allocator> Drain<'_, T, A> { pub fn keep_rest(self); } impl<T, F, A: Allocator> DrainFilter<'_, T, F, A> where F: FnMut(&mut T) -> bool, { pub fn keep_rest(self); } ``` Both these methods cancel draining of elements that were not yet yielded from the iterators. While this needs more testing & documentation, I want at least start the discussion. This may be a potential way out of the "should `DrainFilter` exhaust itself on drop?" argument.
2022-08-22Rollup merge of #99386 - AngelicosPhosphoros:add_retain_test_maybeuninit, ↵Dylan DPC-0/+45
r=JohnTitor Add tests that check `Vec::retain` predicate execution order. This behaviour is documented for `Vec::retain` which means that there is code that rely on that but there weren't tests about that.
2022-07-27Auto merge of #98553 - the8472:next_chunk_opt, r=Mark-Simulacrumbors-0/+10
Optimized vec::IntoIter::next_chunk impl ``` x86_64v1, default test vec::bench_next_chunk ... bench: 696 ns/iter (+/- 22) x86_64v1, pr test vec::bench_next_chunk ... bench: 309 ns/iter (+/- 4) znver2, default test vec::bench_next_chunk ... bench: 17,272 ns/iter (+/- 117) znver2, pr test vec::bench_next_chunk ... bench: 211 ns/iter (+/- 3) ``` On znver2 the default impl seems to be slow due to different inlining decisions. It goes through `core::array::iter_next_chunk` which has a deep call tree.
2022-07-26add test for vec::IntoIter::next_chunk() implThe 8472-0/+10
an adaption of the default impl's doctest
2022-07-17Add tests that check `Vec::retain` predicate execution order.AngelicosPhosphoros-0/+45
2022-07-10Auto merge of #95295 - CAD97:layout-isize, r=scottmcmbors-114/+52
Enforce that layout size fits in isize in Layout As it turns out, enforcing this _in APIs that already enforce `usize` overflow_ is fairly trivial. `Layout::from_size_align_unchecked` continues to "allow" sizes which (when rounded up) would overflow `isize`, but these are now declared as library UB for `Layout`, meaning that consumers of `Layout` no longer have to check this before making an allocation. (Note that this is "immediate library UB;" IOW it is valid for a future release to make this immediate "language UB," and there is an extant patch to do so, to allow Miri to catch this misuse.) See also #95252, [Zulip discussion](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Layout.20Isn't.20Enforcing.20The.20isize.3A.3AMAX.20Rule). Fixes https://github.com/rust-lang/rust/issues/95334 Some relevant quotes: `@eddyb,` https://github.com/rust-lang/rust/pull/95252#issuecomment-1078513769 > [B]ecause of the non-trivial presence of both of these among code published on e.g. crates.io: > > 1. **`Layout` "producers" / `GlobalAlloc` "users"**: smart pointers (including `alloc::rc` copies with small tweaks), collections, etc. > 2. **`Layout` "consumers" / `GlobalAlloc` "providers"**: perhaps fewer of these, but anything built on top of OS APIs like `mmap` will expose `> isize::MAX` allocations (on 32-bit hosts) if they lack extra checks > > IMO the only responsible option is to enforce the `isize::MAX` limit in `Layout`, which: > > * makes `Layout` _sound_ in terms of only ever allowing allocations where `(alloc_base_ptr: *mut u8).offset(size)` is never UB > * frees both "producers" and "consumers" of `Layout` from manually reimplementing the checks > * manual checks can be risky, e.g. if the final size passed to the allocator isn't the one being checked > * this applies retroactively, fixing the overall soundness of existing code with zero transition period or _any_ changes required from users (as long as going through `Layout` is mandatory, making a "choke point") > > > Feel free to quote this comment onto any relevant issue, I might not be able to keep track of developments. `@Gankra,` https://github.com/rust-lang/rust/pull/95252#issuecomment-1078556371 > As someone who spent way too much time optimizing libcollections checks for this stuff and tried to splatter docs about it everywhere on the belief that it was a reasonable thing for people to manually take care of: I concede the point, it is not reasonable. I am wholy spiritually defeated by the fact that _liballoc_ of all places is getting this stuff wrong. This isn't throwing shade at the folks who implemented these Rc features, but rather a statement of how impractical it is to expect anyone out in the wider ecosystem to enforce them if _some of the most audited rust code in the library that defines the very notion of allocating memory_ can't even reliably do it. > > We need the nuclear option of Layout enforcing this rule. Code that breaks this rule is _deeply_ broken and any "regressions" from changing Layout's contract is a _correctness_ fix. Anyone who disagrees and is sufficiently motivated can go around our backs but the standard library should 100% refuse to enable them. cc also `@RalfJung` `@rust-lang/wg-allocators.` Even though this technically supersedes #95252, those potential failure points should almost certainly still get nicer panics than just "unwrap failed" (which they would get by this PR). It might additionally be worth recommending to users of the `Layout` API that they should ideally use `.and_then`/`?` to complete the entire layout calculation, and then `panic!` from a single location at the end of `Layout` manipulation, to reduce the overhead of the checks and optimizations preserving the exact location of each `panic` which are conceptually just one failure: allocation too big. Probably deserves a T-lang and/or T-libs-api FCP (this technically solidifies the [objects must be no larger than `isize::MAX`](https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize) rule further, and the UCG document says this hasn't been RFCd) and a crater run. Ideally, no code exists that will start failing with this addition; if it does, it was _likely_ (but not certainly) causing UB. Changes the raw_vec allocation path, thus deserves a perf run as well. I suggest hiding whitespace-only changes in the diff view.
2022-06-19Fix documentation for with_capacity and reserve families of methodsjmaargh-0/+9
Documentation for the following methods with_capacity with_capacity_in with_capacity_and_hasher reserve reserve_exact try_reserve try_reserve_exact was inconsistent and often not entirely correct where they existed on the following types Vec VecDeque String OsString PathBuf BinaryHeap HashSet HashMap BufWriter LineWriter since the allocator is allowed to allocate more than the requested capacity in all such cases, and will frequently "allocate" much more in the case of zero-sized types (I also checked BufReader, but there the docs appear to be accurate as it appears to actually allocate the exact capacity). Some effort was made to make the documentation more consistent between types as well. Fix with_capacity* methods for Vec Fix *reserve* methods for Vec Fix docs for *reserve* methods of VecDeque Fix docs for String::with_capacity Fix docs for *reserve* methods of String Fix docs for OsString::with_capacity Fix docs for *reserve* methods on OsString Fix docs for with_capacity* methods on HashSet Fix docs for *reserve methods of HashSet Fix docs for with_capacity* methods of HashMap Fix docs for *reserve methods on HashMap Fix expect messages about OOM in doctests Fix docs for BinaryHeap::with_capacity Fix docs for *reserve* methods of BinaryHeap Fix typos Fix docs for with_capacity on BufWriter and LineWriter Fix consistent use of `hasher` between `HashMap` and `HashSet` Fix warning in doc test Add test for capacity of vec with ZST Fix doc test error
2022-06-05Add vec::Drain{,Filter}::keep_restMaybe Waffle-0/+59
These methods allow to cancel draining of unyielded elements.
2022-05-29Use Box::new() instead of box syntax in alloc testsest31-5/+5
2022-04-08add `<[[T; N]]>::flatten`, `<[[T; N]]>::flatten_mut`, and `Vec::<[T; ↵Cyborus04-0/+7
N]>::into_flattened`
2022-03-25Add another assertion without into_iterJörn Horstmann-2/+6
2022-03-25Add a test verifying the number of drop callsJörn Horstmann-0/+24
2022-03-25Adjust tests for isize::MAX allocation always being checkedCAD97-114/+52
2022-03-10Use implicit capture syntax in format_argsT-O-R-U-S-3/+3
This updates the standard library's documentation to use the new syntax. The documentation is worthwhile to update as it should be more idiomatic (particularly for features like this, which are nice for users to get acquainted with). The general codebase is likely more hassle than benefit to update: it'll hurt git blame, and generally updates can be done by folks updating the code if (and when) that makes things more readable with the new format. A few places in the compiler and library code are updated (mostly just due to already having been done when this commit was first authored).
2022-01-09eplace usages of vec![].into_iter with [].into_iterLucas Kent-8/+8
2021-11-19Fix Iterator::advance_by contract inconsistencyThe8472-0/+3
The `advance_by(n)` docs state that in the error case `Err(k)` that k is always less than n. It also states that `advance_by(0)` may return `Err(0)` to indicate an exhausted iterator. These statements are inconsistent. Since only one implementation (Skip) actually made use of that I changed it to return Ok(()) in that case too. While adding some tests I also found a bug in `Take::advance_back_by`.
2021-09-30implement advance_(back_)_by on more iteratorsThe8472-0/+18
2021-08-07Use assert_matches! instead of if let {} elseKornel-113/+103