Commit Graph

42 Commits

Author SHA1 Message Date
The8472 6ed66ebdde add testcase for double-drop during Vec in-place collection
(cherry picked from commit fa89c0fbcfa8f4d44f153b1195ec5a305540ffc4)
2021-04-26 16:47:40 -07:00
Soveu b0092bc995 Vec::dedup optimization - add benches 2021-03-16 14:41:26 +01:00
Soveu 96d6f22a8e
Merge branch 'master' into dedup 2021-03-15 21:51:38 +01:00
Soveu 2285f11724 Vec::dedup optimization - add test for panic 2021-03-15 21:26:22 +01:00
Soveu 2abab1f688 Vec::dedup optimization - add tests 2021-03-15 20:24:35 +01:00
Waffle 1f031d95de Add regression test for `Vec::extend_from_within` leak 2021-03-04 17:10:57 +03:00
Waffle 9c4e3af39d Add test that Vec::spare_capacity_mut doesn't invalidate pointers 2021-03-03 01:00:59 +03:00
Hanif Bin Ariffin fa9af6a9be Added tests to drain an empty vec
Discovered this kind of issue in an unrelated library.
The author copied the tests from here and AFAIK, there are no tests for this particular case.

Signed-off-by: Hanif Bin Ariffin <hanif.ariffin.4326@gmail.com>
2021-02-13 11:18:36 +08: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
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
oxalica 969e552355
Simplify and fix tests 2021-01-24 00:11:51 +08:00
oxalica d6dec1ebe3
Optimize Vec::retain 2021-01-18 01:48:50 +08:00
Aaron Hill 6f91c32da6
Fix new 'unnecessary trailing semicolon' warnings 2020-11-26 17:08:36 -05:00
Alexis Bourget 42271a537a Move vec swap test 2020-10-17 18:48:20 +02:00
Alexis Bourget 4fd06b9bb5 Move vec-macro-repeat test 2020-10-17 18:48:20 +02:00
Alexis Bourget 4af560ecef Move zero-sized-vec-push test 2020-10-17 18:42:14 +02:00
bors 5779815f89 Auto merge of #74194 - mbrubeck:slice-eq, r=sfackler
Add PartialEq impls for Vec <-> slice

This is a follow-up to #71660 and rust-lang/rfcs#2917 to add two more missing vec/slice PartialEq impls:

```
impl<A, B> PartialEq<[B]> for Vec<A> where A: PartialEq<B> { .. }
impl<A, B> PartialEq<Vec<B>> for [A] where A: PartialEq<B> { .. }
```

Since this is insta-stable, it should go through the `@rust-lang/libs` FCP process.  Note that I used version 1.47.0 for the `stable` attribute because I assume this will not merge before the 1.46.0 branch is cut next week.
2020-10-07 01:20:11 +00:00
Alexis Bourget f6a4189d05 Move vec-cycle-wrapped test 2020-09-21 21:50:27 +02:00
Alexis Bourget 6bc0357dad Move vec-cycle test 2020-09-21 21:50:27 +02:00
Mara Bos 1e2dba1e7c Use `T::BITS` instead of `size_of::<T> * 8`. 2020-09-19 06:54:42 +02:00
Ralf Jung 9d0a265b6c
Rollup merge of #76662 - RalfJung:lib-test-miri, r=Mark-Simulacrum
Fix liballoc test suite for Miri

Mostly, fix the regression introduced by https://github.com/rust-lang/rust/pull/75207 that caused slices (i.e., references) to be created to invalid memory or memory that has aliasing pointers that we want to keep valid. @dylni  this changes the type of `check_range` to only require the length, not the full reference to the slice, which indeed is all the information this function requires.

Also reduce the size of a test introduced in https://github.com/rust-lang/rust/pull/70793 to make it not take 3 minutes in Miri.

This makes https://github.com/RalfJung/miri-test-libstd work again.
2020-09-16 08:25:02 +02:00
Dylan DPC fb9bb2b5ca
Rollup merge of #75146 - tmiasko:range-overflow, r=Mark-Simulacrum
Detect overflow in proc_macro_server subspan

* Detect overflow in proc_macro_server subspan
* Add tests for overflow in Vec::drain
* Add tests for overflow in String / VecDeque operations using ranges
2020-09-16 01:30:30 +02:00
Ralf Jung c528d24196 fix slice::check_range aliasing problems 2020-09-15 23:14:41 +02:00
Ralf Jung d888725fba reduce size of test_from_iter_specialization_with_iterator_adapters test in Miri 2020-09-15 23:03:07 +02:00
bors 6cae28165f Auto merge of #76682 - richkadel:vec-take, r=Mark-Simulacrum
Optimize behavior of vec.split_off(0) (take all)

Optimization improvement to `split_off()` so the performance meets the
intuitively expected behavior when `at == 0`, avoiding the current behavior
of copying the entire vector.

The change honors documented behavior that the original vector's
"previous capacity unchanged".

This improvement better supports the pattern for building and flushing a
buffer of elements, such as the following:

```rust
    let mut vec = Vec::new();
    loop {
        vec.push(something);
        if condition_is_met {
            process(vec.split_off(0));
        }
    }
```

`Option` wrapping is the first alternative I thought of, but is much
less obvious and more verbose:

```rust
    let mut capacity = 1;
    let mut vec: Option<Vec<Stuff>> = None;
    loop {
        vec.get_or_insert_with(|| Vec::with_capacity(capacity)).push(something);
        if condition_is_met {
            capacity = vec.capacity();
            process(vec.take().unwrap());
        }
    }
```

Directly using `mem::replace()` (instead of  calling`split_off()`) could work,
but `mem::replace()` is a more advanced tool for Rust developers, and in
this case, I believe developers would assume the standard library should
be sufficient for the purpose described here.

The benefit of the approach to this change is it does not change the
existing API contract, but improves the peformance of `split_off(0)` for
`Vec`, `String` (which delegates `split_off()` to `Vec`), and any other
existing use cases.

This change adds tests to validate the behavior of `split_off()` with
regard to capacity, as originally documented, and confirm that behavior
still holds, when `at == 0`.

The change is an implementation detail, and does not require a
documentation change, but documenting the new behavior as part of its
API contract may benefit future users.

(Let me know if I should make that documentation update.)

Note, for future consideration:

I think it would be helpful to introduce an additional method to `Vec`
(if not also to `String`):

```
    pub fn take_all(&mut self) -> Self {
        self.split_off(0)
    }
```

This would make it more clear how `Vec` supports the pattern, and make
it easier to find, since the behavior is similar to other `take()`
methods in the Rust standard library.

r? `@wesleywiser`
FYI: `@tmandry`
2020-09-15 05:01:17 +00:00
Rich Kadel 79aa9b15d7 Optimize behavior of vec.split_off(0) (take all)
Optimization improvement to `split_off()` so the performance meets the
intuitively expected behavior when `at == 0`, avoiding the current
behavior of copying the entire vector.

The change honors documented behavior that the method leaves the
original vector's "previous capacity unchanged".

This improvement better supports the pattern for building and flushing a
buffer of elements, such as the following:

```rust
    let mut vec = Vec::new();
    loop {
        vec.push(something);
        if condition_is_met {
            process(vec.split_off(0));
        }
    }
```

`Option` wrapping is the first alternative I thought of, but is much
less obvious and more verbose:

```rust
    let mut capacity = 1;
    let mut vec: Option<Vec<Stuff>> = None;
    loop {
        vec.get_or_insert_with(|| Vec::with_capacity(capacity)).push(something);
        if condition_is_met {
            capacity = vec.capacity();
            process(vec.take().unwrap());
        }
    }
```

Directly applying `mem::replace()` could work, but `mem::` functions are
typically a last resort, when a developer is actively seeking better
performance than the standard library provides, for example.

The benefit of the approach to this change is it does not change the
existing API contract, but improves the peformance of `split_off(0)` for
`Vec`, `String` (which delegates `split_off()` to `Vec`), and any other
existing use cases.

This change adds tests to validate the behavior of `split_off()` with
regard to capacity, as originally documented, and confirm that behavior
still holds, when `at == 0`.

The change is an implementation detail, and does not require a
documentation change, but documenting the new behavior as part of its
API contract may benefit future users.

(Let me know if I should make that documentation update.)

Note, for future consideration:

I think it would be helpful to introduce an additional method to `Vec`
(if not also to `String`):

```
    pub fn take_all(&mut self) -> Self {
        self.split_off(0)
    }
```

This would make it more clear how `Vec` supports the pattern, and make
it easier to find, since the behavior is similar to other `take()`
methods in the Rust standard library.
2020-09-13 14:32:29 -07:00
Ralf Jung 71a5c464d1 note that test_stable_pointers does not reflect a stable guarantee 2020-09-13 18:55:08 +02:00
Dylan DPC 1b24f1401d
Rollup merge of #76324 - ayushmishra2005:move_vec_tests_in_library, r=matklad
Move Vec slice UI tests in library

Moved some of Vec slice UI tests in Library as a part of #76268

r? @matklad
2020-09-07 01:18:07 +02:00
Dylan DPC e488c4f187
Rollup merge of #76273 - CraftSpider:master, r=matklad
Move some Vec UI tests into alloc unit tests

A bit of work towards #76268, makes a number of the Vec UI tests that are simply running code into unit tests. Ensured that they are being run when testing liballoc locally.
2020-09-07 01:17:45 +02:00
Ayush Kumar Mishra d16bbd1cb0 Move Vec slice UI tests in library 2020-09-04 17:18:26 +05:30
Tomasz Miąsko d98bac4e4e Add tests for overflow in Vec::drain 2020-09-04 23:16:53 +02:00
Rune Tynan 2278c7255a
Remove vec-to_str.rs, merge the remaining test in with vec 2020-09-03 15:43:07 -04:00
The8472 435219dd82 remove empty Vec extend optimization
The optimization meant that every extend code path had to emit llvm
IR for from_iter and extend spec_extend, which likely impacts
compile times while only improving a few edge-cases
2020-09-03 20:59:35 +02:00
The8472 80638330f2 support in-place collect for MapWhile adapters 2020-09-03 20:59:32 +02:00
The8472 5530858a08 generalize in-place collect to types of same size and alignment 2020-09-03 20:59:31 +02:00
The8472 470bf54f94 test drops during in-place iteration 2020-09-03 20:59:27 +02:00
The8472 fd16202e36 include in-place .zip() in test 2020-09-03 20:59:21 +02:00
The8472 2b0b2ae9f6 additional specializations tests 2020-09-03 20:59:17 +02:00
The8472 bb2d533bb9 in-place collect for Vec. Box<[]> and BinaryHeap IntoIter and some adapters 2020-09-03 20:59:03 +02:00
Rune Tynan 3e29fdb0fb
Remove a number of vec UI tests, make them unit tests in the alloc library 2020-09-03 01:40:15 -04:00
Matt Brubeck b4b383981a Add PartialEq impls for Vec <-> slice 2020-08-27 13:32:36 -07:00
mark 2c31b45ae8 mv std libs to library/ 2020-07-27 19:51:13 -05:00