summary refs log tree commit diff
path: root/library/alloc/src/vec/mod.rs
AgeCommit message (Collapse)AuthorLines
2021-06-02Update expressions where we can use array's IntoIterator implementationMuhammad Mominul Huque-4/+4
2021-05-24Avoid a double drop in Vec::dedup if a destructor panicsGiacomo Stevanato-2/+3
2021-05-05alloc: Add unstable Cfg feature `no-global_oom_handling`John Ericson-2/+54
For certain sorts of systems, programming, it's deemed essential that all allocation failures be explicitly handled where they occur. For example, see Linus Torvald's opinion in [1]. Merely not calling global panic handlers, or always `try_reserving` first (for vectors), is not deemed good enough, because the mere presence of the global OOM handlers is burdens static analysis. One option for these projects to use rust would just be to skip `alloc`, rolling their own allocation abstractions. But this would, in my opinion be a real shame. `alloc` has a few `try_*` methods already, and we could easily have more. Features like custom allocator support also demonstrate and existing to support diverse use-cases with the same abstractions. A natural way to add such a feature flag would a Cargo feature, but there are currently uncertainties around how std library crate's Cargo features may or not be stable, so to avoid any risk of stabilizing by mistake we are going with a more low-level "raw cfg" token, which cannot be interacted with via Cargo alone. Note also that since there is no notion of "default cfg tokens" outside of Cargo features, we have to invert the condition from `global_oom_handling` to to `not(no_global_oom_handling)`. This breaks the monotonicity that would be important for a Cargo feature (i.e. turning on more features should never break compatibility), but it doesn't matter for raw cfg tokens which are not intended to be "constraint solved" by Cargo or anything else. To support this use-case we create a new feature, "global-oom-handling", on by default, and put the global OOM handler infra and everything else it that depends on it behind it. By default, nothing is changed, but users concerned about global handling can make sure it is disabled, and be confident that all OOM handling is local and explicit. For this first iteration, non-flat collections are outright disabled. `Vec` and `String` don't yet have `try_*` allocation methods, but are kept anyways since they can be oom-safely created "from parts", and we hope to add those `try_` methods in the future. [1]: https://lore.kernel.org/lkml/CAHk-=wh_sNLoz84AUUzuqXEsYH35u=8HV3vK-jbRbJ_B-JjGrg@mail.gmail.com/
2021-04-28Stabilize vec_extend_from_withinAmanieu d'Antras-3/+1
2021-04-21Remove duplicated fn(Box<[T]>) -> Vec<T>Caleb Sander-2/+1
2021-04-18Slightly change wording and fix typo in vec/mod.rsWaffle Lapkin-2/+2
2021-04-12Improve code example for length comparisonGuillaume Gomez-1/+1
2021-03-31panic early when TrustedLen indicates a length > usize::MAXThe8472-0/+8
2021-03-28Auto merge of #83582 - jyn514:might-not, r=joshtriplettbors-3/+3
may not -> might not may not -> might not "may not" has two possible meanings: 1. A command: "You may not stay up past your bedtime." 2. A fact that's only sometimes true: "Some cities may not have bike lanes." In some cases, the meaning is ambiguous: "Some cars may not have snow tires." (do the cars *happen* to not have snow tires, or is it physically impossible for them to have snow tires?) This changes places where the standard library uses the "description of fact" meaning to say "might not" instead. This is just `std::vec` for now - if you think this is a good idea I can convert the rest of the standard library.
2021-03-27may not -> might notJoshua Nelson-3/+3
"may not" has two possible meanings: 1. A command: "You may not stay up past your bedtime." 2. A fact that's only sometimes true: "Some cities may not have bike lanes." In some cases, the meaning is ambiguous: "Some cars may not have snow tires." (do the cars *happen* to not have snow tires, or is it physically impossible for them to have snow tires?) This changes places where the standard library uses the "description of fact" meaning to say "might not" instead. This is just `std::vec` for now - if you think this is a good idea I can convert the rest of the standard library.
2021-03-26Use iter::zip in library/Josh Stone-6/+3
2021-03-25Change wordingMichael Howell-2/+2
2021-03-24Add docs for Vec::from functionsMichael Howell-0/+61
Part of #51430
2021-03-18Rollup merge of #82191 - Soveu:dedup, r=nagisaDylan DPC-6/+89
Vec::dedup_by optimization Now `Vec::dedup_by` drops items in-place as it goes through them. From my benchmarks, it is around 10% faster when T is small, with no major regression when otherwise. I used `ptr::copy` instead of conditional `ptr::copy_nonoverlapping`, because the latter had some weird performance issues on my ryzen laptop (it was 50% slower on it than on intel/sandybridge laptop) It would be good if someone was able to reproduce these results.
2021-03-16Rollup merge of #83072 - henryboisdequin:patch-1, r=Dylan-DPCYuki Okushi-3/+3
Update `Vec` docs Fix typos/nits in `Vec` docs
2021-03-15Merge branch 'master' into dedupSoveu-37/+53
2021-03-15Vec::dedup optimization - finishing polishesSoveu-11/+7
2021-03-13Update `Vec` docsHenry Boisdequin-3/+3
2021-03-04Add regression test for `Vec::extend_from_within` leakWaffle-3/+5
2021-03-04Fix leak in Vec::extend_from_withinWaffle-16/+27
Previously vec's len was updated only after full copy, making the method leak if T::clone panic!s. This commit makes `Vec::extend_from_within` (or, more accurately, it's `T: Clone` specialization) update vec's len on every iteration, fixing the issue. `T: Copy` specialization was not affected by the issue b/c it doesn't call user specified code (as, e.g. `T::clone`), and instead calls `ptr::copy_nonoverlapping`.
2021-03-04Rollup merge of #82564 - WaffleLapkin:revert_spare_mut, r=RalfJungYuki Okushi-10/+14
Revert `Vec::spare_capacity_mut` impl to prevent pointers invalidation The implementation was changed in #79015. Later it was [pointed out](https://github.com/rust-lang/rust/issues/81944#issuecomment-782849785) that the implementation invalidates pointers to the buffer (initialized elements) by creating a unique reference to the buffer. This PR reverts the implementation. r? ```@RalfJung```
2021-03-03Update library/alloc/src/vec/mod.rsWaffle Lapkin-1/+1
Co-authored-by: Ralf Jung <post@ralfj.de>
2021-03-03Make Vec::split_at_spare_mut impl safer & simplierWaffle-9/+5
2021-02-27Revert `Vec::spare_capacity_mut` impl to prevent pointers invalidationWaffle-1/+9
2021-02-25Convert primitives to use intra-doc linksJoshua Nelson-4/+2
2021-02-24library: Normalize safety-for-unsafe-block commentsMiguel Ojeda-8/+9
Almost all safety comments are of the form `// SAFETY:`, so normalize the rest and fix a few of them that should have been a `/// # Safety` section instead. Furthermore, make `tidy` only allow the uppercase form. While currently `tidy` only checks `core`, it is a good idea to prevent `core` from drifting to non-uppercase comments, so that later we can start checking `alloc` etc. too. Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2021-02-23Rollup merge of #81154 - dylni:improve-design-of-assert-len, r=KodrAusDylan DPC-3/+3
Improve design of `assert_len` It was discussed in the [tracking issue](https://github.com/rust-lang/rust/issues/76393#issuecomment-761765448) that `assert_len`'s name and usage are confusing. This PR improves them based on a suggestion by ``@scottmcm`` in that issue. I also improved the documentation to make it clearer when you might want to use this method. Old example: ```rust let range = range.assert_len(slice.len()); ``` New example: ```rust let range = range.ensure_subset_of(..slice.len()); ``` Fixes #81157
2021-02-17Vec::dedup optimization - panic gracefullySoveu-16/+65
2021-02-16Vec::dedup optimizationSoveu-6/+44
2021-02-13Rollup merge of #81811 - schteve:fix_vec_retain_doc_test, r=m-ou-seYuki Okushi-3/+4
Fix doc test for Vec::retain(), now passes clippy::eval_order_dependence Doc test for Vec::retain() works correctly but is flagged by clippy::eval_order_dependence. Fix avoids the issue by using an iterator instead of an index.
2021-02-12Update new usage of `assert_len`dylni-2/+2
2021-02-12Rename `Range::ensure_subset_of` to `slice::range`dylni-1/+1
2021-02-12Fix possible soundness issue in `ensure_subset_of`dylni-1/+1
2021-02-12Improve design of `assert_len`dylni-1/+1
2021-02-11Auto merge of #81126 - oxalica:retain-early-drop, r=m-ou-sebors-11/+64
Optimize Vec::retain Use `copy_non_overlapping` instead of `swap` to reduce memory writes, like what we've done in #44355 and `String::retain`. #48065 already tried to do this optimization but it is reverted in #67300 due to bad codegen of `DrainFilter::drop`. This PR re-implement the drop-then-move approach. I did a [benchmark](https://gist.github.com/oxalica/3360eec9376f22533fcecff02798b698) on small-no-drop, small-need-drop, large-no-drop elements with different predicate functions. It turns out that the new implementation is >20% faster in average for almost all cases. Only 2/24 cases are slower by 3% and 5%. See the link above for more detail. I think regression in may-panic cases is due to drop-guard preventing some optimization. If it's permitted to leak elements when predicate function of element's `drop` panic, the new implementation should be almost always faster than current one. I'm not sure if we should leak on panic, since there is indeed an issue (#52267) complains about it before.
2021-02-10update tracking issue for vec_split_at_spareAshley Mannix-1/+1
2021-02-06Fix doc test for Vec::retain(), now passes clippy::eval_order_dependenceSteve Heindel-3/+4
2021-02-03Add note to `Vec::split_at_spare_mut` docs that the method is low-levelWaffle-0/+15
2021-02-03fix typo in library/alloc/src/vec/mod.rsWaffle Lapkin-1/+1
Co-authored-by: the8472 <the8472@users.noreply.github.com>
2021-02-03Make Vec::split_at_spare_mut publicWaffle-1/+38
This commit introduces a new method to the public API, under `vec_split_at_spare` feature gate: ```rust impl<T, A: Allocator> impl Vec<T, A> { pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]); } ``` The method returns 2 slices, one slice references the content of the vector, and the other references the remaining spare capacity. The method was previously implemented while adding `Vec::extend_from_within`, and used to implement `Vec::spare_capacity_mut` (as the later is just a subset of former one).
2021-02-02Auto merge of #79015 - WaffleLapkin:vec_append_from_within, r=KodrAusbors-4/+109
add `Vec::extend_from_within` method under `vec_extend_from_within` feature gate Implement <https://github.com/rust-lang/rfcs/pull/2714> ### tl;dr This PR adds a `extend_from_within` method to `Vec` which allows copying elements from a range to the end: ```rust #![feature(vec_extend_from_within)] let mut vec = vec![0, 1, 2, 3, 4]; vec.extend_from_within(2..); assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]); vec.extend_from_within(..2); assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]); vec.extend_from_within(4..8); assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]); ``` ### Implementation notes Originally I've copied `@Shnatsel's` [implementation](https://github.com/WanzenBug/rle-decode-helper/blob/690742a0de158d391b7bde1a0c71cccfdad33ab3/src/lib.rs#L74) with some minor changes to support other ranges: ```rust pub fn append_from_within<R>(&mut self, src: R) where T: Copy, R: RangeBounds<usize>, { let len = self.len(); let Range { start, end } = src.assert_len(len);; let count = end - start; self.reserve(count); unsafe { // This is safe because `reserve()` above succeeded, // so `self.len() + count` did not overflow usize ptr::copy_nonoverlapping( self.get_unchecked(src.start), self.as_mut_ptr().add(len), count, ); self.set_len(len + count); } } ``` But then I've realized that this duplicates most of the code from (private) `Vec::append_elements`, so I've used it instead. Then I've applied `@KodrAus` suggestions from https://github.com/rust-lang/rust/pull/79015#issuecomment-727200852.
2021-02-02update tracking issue for vec_extend_from_withinAshley Mannix-1/+1
2021-01-31add `Vec::extend_from_within` methodWaffle-4/+109
Implement <https://github.com/rust-lang/rfcs/pull/2714>, changes from the RFC: - Rename the method `append_from_within` => `extend_from_within` - Loose :Copy bound => :Clone - Specialize in case of :Copy This commit also adds `Vec::split_at_spare` private method and use it to implement `Vec::spare_capacity_mut` and `Vec::extend_from_within`. This method returns 2 slices - initialized elements (same as `&mut vec[..]`) and uninitialized but allocated space (same as `vec.spare_capacity_mut()`).
2021-01-29Updated Vec::splice documentationChan Kwan Yin-1/+1
Replacing with equal number of values does not increase the length of the vec. Reference: https://stackoverflow.com/a/62559271/3990767
2021-01-26shrink_to shouldn't panic on len greater than capacityThom Wiggers-6/+6
2021-01-24Fix and simplifyoxalica-22/+22
2021-01-22Add doc aliases for memory allocationsYoshua Wuyts-0/+7
- Vec::with_capacity / Box::new -> alloc + malloc - Box::new_zeroed -> calloc - Vec::{reserve,reserve_exact,try_reserve_exact,shrink_to_fit,shrink_to} -> realloc
2021-01-21Remove link to current sectionIvan Tham-2/+1
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2021-01-20Add more details explaning the Vec visualizationIvan Tham-20/+22
Suggested by oli-obk
2021-01-20Add Vec visualization to understand capacityIvan Tham-0/+21
Visualize vector while differentiating between stack and heap. Inspired by cheats.rs, as this is probably the first place beginner go, they could understand stack and heap, length and capacity with this. Not sure if adding this means we should add to other places too. Superseeds #76066