Commit graph

79 commits

Author SHA1 Message Date
Ivan Tham
eeac70c567
Merge same condition branch in vec spec_extend 2021-04-15 11:58:02 +08:00
Guillaume Gomez
b89c464bed
Improve code example for length comparison 2021-04-12 19:59:52 +02:00
Dylan DPC
542f441d44
Rollup merge of #83629 - the8472:fix-inplace-panic-on-drop, r=m-ou-se
Fix double-drop in `Vec::from_iter(vec.into_iter())` specialization when items drop during panic

This fixes the double-drop but it leaves a behavioral difference compared to the default implementation intact: In the default implementation the source and the destination vec are separate objects, so they get dropped separately. Here they share an allocation and the latter only exists as a pointer into the former. So if dropping the former panics then this fix will leak more items than the default implementation would. Is this acceptable or should the specialization also mimic the default implementation's drops-during-panic behavior?

Fixes #83618

`@rustbot` label T-libs-impl
2021-04-02 19:57:31 +02:00
The8472
ad3a791e2a panic early when TrustedLen indicates a length > usize::MAX 2021-03-31 23:09:28 +02:00
The8472
421f5d282a fix double-drop in in-place collect specialization 2021-03-29 04:48:13 +02:00
bors
0239876020 Auto merge of #83582 - jyn514:might-not, r=joshtriplett
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-28 14:16:03 +00:00
Joshua Nelson
e051db6838 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-27 16:01:16 -04:00
Josh Stone
3b1f5e3462 Use iter::zip in library/ 2021-03-26 09:32:29 -07:00
Michael Howell
ef1bd5776d
Change wording 2021-03-25 02:58:34 -07:00
Michael Howell
b3321e2860 Add docs for Vec::from functions
Part of #51430
2021-03-24 18:43:18 -07:00
The8472
6c67e55270 specialize in-place collection further via TrustedRandomAccess
This allows the optimizer to turn certain iterator pipelines such as

```rust
let vec = vec![0usize; 100];
vec.into_iter().map(|e| e as isize).collect::<Vec<_>>()
```

into a noop.

The optimization only applies when iterator sources are  `T: Copy`
since `impl TrustedRandomAccess for IntoIter<T>`.
No such requirement applies to the output type (`Iterator::Item`).
2021-03-21 20:54:06 +01:00
Dylan DPC
90797ef008
Rollup merge of #82191 - Soveu:dedup, r=nagisa
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-18 00:28:04 +01:00
Yuki Okushi
b6df781643
Rollup merge of #83072 - henryboisdequin:patch-1, r=Dylan-DPC
Update `Vec` docs

Fix typos/nits in `Vec` docs
2021-03-16 23:53:54 +09:00
Soveu
96d6f22a8e
Merge branch 'master' into dedup 2021-03-15 21:51:38 +01:00
Soveu
afdbc9ece1 Vec::dedup optimization - finishing polishes 2021-03-15 20:36:29 +01:00
Henry Boisdequin
81d1d82596
Update Vec docs 2021-03-13 07:58:03 +05:30
Waffle
1f031d95de Add regression test for Vec::extend_from_within leak 2021-03-04 17:10:57 +03:00
Waffle
84e9608596 Fix leak in Vec::extend_from_within
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-04 17:10:57 +03:00
Yuki Okushi
290117f7d9
Rollup merge of #82564 - WaffleLapkin:revert_spare_mut, r=RalfJung
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-04 20:01:06 +09:00
Waffle Lapkin
950f12119e
Update library/alloc/src/vec/mod.rs
Co-authored-by: Ralf Jung <post@ralfj.de>
2021-03-03 20:04:20 +03:00
Waffle
a1835bcb01 Make Vec::split_at_spare_mut impl safer & simplier 2021-03-03 01:04:20 +03:00
bors
795a934b51 Auto merge of #82043 - tmiasko:may-have-side-effect, r=kennytm
Turn may_have_side_effect into an associated constant

The `may_have_side_effect` is an implementation detail of `TrustedRandomAccess`
trait. It describes if obtaining an iterator element may have side effects. It
is currently implemented as an associated function.

Turn `may_have_side_effect` into an associated constant. This makes the
value immediately available to the optimizer.
2021-03-02 16:08:32 +00:00
Waffle
2f04a793ae Revert Vec::spare_capacity_mut impl to prevent pointers invalidation 2021-02-27 00:27:34 +03:00
Joshua Nelson
9a75f4fed1 Convert primitives to use intra-doc links 2021-02-25 20:31:53 -05:00
Miguel Ojeda
eefec8abda library: Normalize safety-for-unsafe-block comments
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-24 06:13:42 +01:00
Dylan DPC
72e6d51583
Rollup merge of #81154 - dylni:improve-design-of-assert-len, r=KodrAus
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-23 02:51:43 +01:00
Soveu
c114894b90 Vec::dedup optimization - panic gracefully 2021-02-17 17:21:12 +01:00
Soveu
1825810a89 Vec::dedup optimization 2021-02-16 18:48:42 +01:00
Tomasz Miąsko
dc3304c341 Turn may_have_side_effect into an associated constant
The `may_have_side_effect` is an implementation detail of `TrustedRandomAccess`
trait. It describes if obtaining an iterator element may have side effects. It
is currently implemented as an associated function.

Turn `may_have_side_effect` into an associated constant. This makes the
value immediately available to the optimizer.
2021-02-15 17:36:29 +01:00
Yuki Okushi
4cb381037e
Rollup merge of #81811 - schteve:fix_vec_retain_doc_test, r=m-ou-se
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-13 16:36:40 +09:00
dylni
fe4fe19ddc Update new usage of assert_len 2021-02-12 22:03:39 -05:00
dylni
5d519eaa6e Rename Range::ensure_subset_of to slice::range 2021-02-12 22:01:04 -05:00
dylni
cb647f3e8e Fix possible soundness issue in ensure_subset_of 2021-02-12 22:01:04 -05:00
dylni
9d29793614 Improve design of assert_len 2021-02-12 22:01:04 -05:00
bors
1efd804983 Auto merge of #81126 - oxalica:retain-early-drop, r=m-ou-se
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-11 04:40:57 +00:00
Ashley Mannix
8ff7b75c01
update tracking issue for vec_split_at_spare 2021-02-10 09:50:59 +10:00
Steve Heindel
0488afd967 Fix doc test for Vec::retain(), now passes clippy::eval_order_dependence 2021-02-06 21:20:28 -05:00
Waffle
76223fafb4 Add note to Vec::split_at_spare_mut docs that the method is low-level 2021-02-03 14:14:55 +03:00
Waffle Lapkin
476a57a628
fix typo in library/alloc/src/vec/mod.rs
Co-authored-by: the8472 <the8472@users.noreply.github.com>
2021-02-03 13:53:58 +03:00
Waffle
cd6dad641c Make Vec::split_at_spare_mut public
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-03 01:56:51 +03:00
bors
f6cb45ad01 Auto merge of #79015 - WaffleLapkin:vec_append_from_within, r=KodrAus
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](690742a0de/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-02 09:12:53 +00:00
Ashley Mannix
125ec782bd
update tracking issue for vec_extend_from_within 2021-02-02 17:47:55 +10:00
Waffle
d5c221107e add Vec::extend_from_within method
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-31 22:30:19 +03:00
Chan Kwan Yin
02094f9962
Updated Vec::splice documentation
Replacing with equal number of values does not increase the length of the vec.

Reference: https://stackoverflow.com/a/62559271/3990767
2021-01-29 12:21:53 +08:00
Thom Wiggers
d069c58e78
shrink_to shouldn't panic on len greater than capacity 2021-01-26 19:25:37 +01:00
oxalica
2a11c57fb0
Fix and simplify 2021-01-24 00:11:51 +08:00
Yoshua Wuyts
7d102383f9 Add doc aliases for memory allocations
- 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-22 18:15:28 +01:00
Yuki Okushi
b76f0f92ab
Rollup merge of #81179 - CPerezz:fix_interal_doc_warns, r=jyn514
Fix broken links with `--document-private-items` in the standard library

As it was suggested in #81037 `SpecFromIter` is not
in the scope and therefore we get a warning when we try to
do document private intems in `rust/library/alloc/`.

This addresses #81037 by adding the trait in the scope as ```@jyn514```
suggested and also adding an `allow(unused_imports)` flag so that
the compiler does not complain, Since the trait is not used
per se in the code, it's just needed to have properly documented
docs.
2021-01-21 20:04:50 +09:00
Ivan Tham
9844d9ee97
Remove link to current section
Co-authored-by: Mara Bos <m-ou.se@m-ou.se>
2021-01-21 13:18:12 +08:00
Ivan Tham
9f338e18af Add more details explaning the Vec visualization
Suggested by oli-obk
2021-01-20 23:41:56 +08:00