Commit Graph

558 Commits

Author SHA1 Message Date
bors
b573e10d21 Auto merge of #98553 - the8472:next_chunk_opt, r=Mark-Simulacrum
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-27 01:12:30 +00:00
The 8472
2f9f2e507e Optimized vec::IntoIter::next_chunk impl
```
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)
```

The znver2 default impl seems to be slow due to inlining decisions. It goes through `core::array::iter_next_chunk`
which has a deeper call tree.
2022-07-26 20:31:43 +02:00
AngelicosPhosphoros
86d445eda8 Support vec zero-alloc optimization for tuples and byte arrays
* Implement IsZero trait for tuples up to 8 IsZero elements;
* Implement IsZero for u8/i8, leading to implementation of it for arrays of them too;
* Add more codegen tests for this optimization.
* Lower size of array for IsZero trait because it fails to inline checks
2022-07-24 15:56:39 -04:00
Duarte Nunes
a85ee3ed91 add code examples 2022-07-14 11:47:06 -03:00
Duarte Nunes
8d35ab3806 rustdoc 2022-07-13 22:04:15 -03:00
Duarte Nunes
050115c0d4 typo 2022-07-13 21:49:31 -03:00
Duarte Nunes
c9ec7aa0d7 changes to wording 2022-07-13 21:48:18 -03:00
Duarte Nunes
9cd66be235 docs: be less harsh in wording for Vec::from_raw_parts
In particular, be clear that it is sound to specify memory not
originating from a previous `Vec` allocation. That is already suggested
in other parts of the documentation about zero-alloc conversions to Box<[T]>.

Incorporate a constraint from `slice::from_raw_parts` that was missing
but needs to be fulfilled, since a `Vec` can be converted into a slice.
2022-07-13 14:29:35 -03:00
bors
f99f9e48ed Auto merge of #98755 - nnethercote:faster-vec-insert, r=cuviper
Optimize `Vec::insert` for the case where `index == len`.

By skipping the call to `copy` with a zero length. This makes it closer
to `push`.

I did this recently for `SmallVec`
(https://github.com/servo/rust-smallvec/pull/282) and it was a big perf win in
one case. Although I don't have a specific use case in mind, it seems
worth doing it for `Vec` as well.

Things to note:
- In the `index < len` case, the number of conditions checked is
  unchanged.
- In the `index == len` case, the number of conditions checked increases
  by one, but the more expensive zero-length copy is avoided.
- In the `index > len` case the code now reserves space for the extra
  element before panicking. This seems like an unimportant change.

r? `@cuviper`
2022-07-03 09:36:37 +00:00
bors
ada8c80bed Auto merge of #98673 - pietroalbini:pa-bootstrap-update, r=Mark-Simulacrum
Bump bootstrap compiler

r? `@Mark-Simulacrum`
2022-07-03 06:55:50 +00:00
Pietro Albini
6b2d3d5f3c update cfg(bootstrap)s 2022-07-01 15:48:23 +02:00
Nicholas Nethercote
679c5ee244 Optimize Vec::insert for the case where index == len.
By skipping the call to `copy` with a zero length. This makes it closer
to `push`.

I did this recently for `SmallVec`
(https://github.com/servo/rust-smallvec/pull/282) and it was a big perf win in
one case. Although I don't have a specific use case in mind, it seems
worth doing it for `Vec` as well.

Things to note:
- In the `index < len` case, the number of conditions checked is
  unchanged.
- In the `index == len` case, the number of conditions checked increases
  by one, but the more expensive zero-length copy is avoided.
- In the `index > len` case the code now reserves space for the extra
  element before panicking. This seems like an unimportant change.
2022-07-01 06:46:30 +10:00
Miguel Ojeda
83addf2540 alloc: fix no_global_oom_handling warnings
Rust 1.62.0 introduced a couple new `unused_imports` warnings
in `no_global_oom_handling` builds, making a total of 5 warnings:

```txt
warning: unused import: `Unsize`
 --> library/alloc/src/boxed/thin.rs:6:33
  |
6 | use core::marker::{PhantomData, Unsize};
  |                                 ^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `from_fn`
  --> library/alloc/src/string.rs:51:18
   |
51 | use core::iter::{from_fn, FusedIterator};
   |                  ^^^^^^^

warning: unused import: `core::ops::Deref`
  --> library/alloc/src/vec/into_iter.rs:12:5
   |
12 | use core::ops::Deref;
   |     ^^^^^^^^^^^^^^^^

warning: associated function `shrink` is never used
   --> library/alloc/src/raw_vec.rs:424:8
    |
424 |     fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> {
    |        ^^^^^^
    |
    = note: `#[warn(dead_code)]` on by default

warning: associated function `forget_remaining_elements` is never used
   --> library/alloc/src/vec/into_iter.rs:126:19
    |
126 |     pub(crate) fn forget_remaining_elements(&mut self) {
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^
```

This patch cleans them so that projects compiling `alloc` without
infallible allocations do not see the warnings. It also enables
the use of `-Dwarnings`.

The couple `dead_code` ones may be reverted when some fallible
allocation support starts using them.

Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-06-29 04:44:23 +02:00
jmaargh
95dc353006 Fix documentation for with_capacity and reserve families of methods
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-19 20:46:49 +01:00
Maybe Waffle
50c98a8c46 Add vec::Drain{,Filter}::keep_rest
These methods allow to cancel draining of unyielded elements.
2022-06-05 14:28:25 +04:00
bors
20976bae5c Auto merge of #97293 - est31:remove_box, r=oli-obk
Add #[rustc_box] and use it inside alloc

This commit adds an alternative content boxing syntax, and uses it inside alloc.

```Rust
#![feature(box_syntax)]

fn foo() {
    let foo = box bar;
}
```

is equivalent to

```Rust
#![feature(rustc_attrs)]

fn foo() {
    let foo = #[rustc_box] Box::new(bar);
}
```

The usage inside the very performance relevant code in
liballoc is the only remaining relevant usage of box syntax
in the compiler (outside of tests, which are comparatively easy to port).

box syntax was originally designed to be used by all Rust
developers. This introduces a replacement syntax more tailored
to only being used inside the Rust compiler, and with it,
lays the groundwork for eventually removing box syntax.

[Earlier work](https://github.com/rust-lang/rust/pull/87781#issuecomment-894714878) by `@nbdd0121` to lower `Box::new` to `box` during THIR -> MIR building ran into borrow checker problems, requiring the lowering to be adjusted in a way that led to [performance regressions](https://github.com/rust-lang/rust/pull/87781#issuecomment-894872367). The proposed change in this PR lowers `#[rustc_box] Box::new` -> `box` in the AST -> HIR lowering step, which is way earlier in the compiler, and thus should cause less issues both performance wise as well as regarding type inference/borrow checking/etc. Hopefully, future work can move the lowering further back in the compiler, as long as there are no performance regressions.
2022-06-02 13:20:19 +00:00
bors
395a09c3da Auto merge of #97553 - nbdd0121:lib, r=Mark-Simulacrum
Add `#[inline]` to `Vec`'s `Deref/DerefMut`

This should help #97552 (although I haven't verified).
2022-06-01 04:52:11 +00:00
est31
535e28b6c6 Use #[rustc_box] in alloc instead of box syntax 2022-06-01 02:28:34 +02:00
Matthias Krüger
0d1e5465f3 Rollup merge of #97578 - ojeda:checkpatch, r=JohnTitor
alloc: remove repeated word in comment

Linux's `checkpatch.pl` reports:

```txt
#42544: FILE: rust/alloc/vec/mod.rs:2692:
WARNING: Possible repeated word: 'to'
+            // - Elements are :Copy so it's OK to to copy them, without doing
```

Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-31 23:11:35 +02:00
bors
16a0d03698 Auto merge of #97521 - SkiFire13:clarify-vec-as-ptr, r=Dylan-DPC
Clarify the guarantees of Vec::as_ptr and Vec::as_mut_ptr when there's no allocation

Currently the documentation says they return a pointer to the vector's buffer, which has the implied precondition that the vector allocated some memory. However `Vec`'s documentation also specifies that it won't always allocate, so it's unclear whether the pointer returned is valid in that case. Of course you won't be able to read/write actual bytes to/from it since the capacity is 0, but there's an exception: zero sized read/writes. They are still valid as long as the pointer is not null and the memory it points to wasn't deallocated, but `Vec::as_ptr` and `Vec::as_mut_ptr` don't specify that's not the case. This PR thus specifies they are actually valid for zero sized reads since `Vec` is implemented to hold a dangling pointer in those cases, which is neither null nor was deallocated.
2022-05-31 12:14:51 +00:00
Miguel Ojeda
5dae6c1b96 alloc: remove repeated word in comment
Linux's `checkpatch.pl` reports:

```txt
#42544: FILE: rust/alloc/vec/mod.rs:2692:
WARNING: Possible repeated word: 'to'
+            // - Elements are :Copy so it's OK to to copy them, without doing
```

Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2022-05-31 12:33:31 +02:00
Gary Guo
0a7a0ff4d9 Add #[inline] to Vec's Deref/DerefMut 2022-05-30 15:11:53 +01:00
Giacomo Stevanato
8ef2dd70e6 Clarify the guarantees of Vec::as_ptr and Vec::as_mut_ptr when there's no allocation 2022-05-29 17:43:35 +02:00
Matthias Krüger
4254f922db Rollup merge of #95214 - tbu-:pr_vec_append_doc, r=Mark-Simulacrum
Remove impossible panic note from `Vec::append`

Neither the number of elements in a vector can overflow a `usize`, nor
can the amount of elements in two vectors.
2022-05-28 01:11:46 +02:00
Dylan DPC
e5cf3cb97d Rollup merge of #97087 - Nilstrieb:clarify-slice-iteration-order, r=dtolnay
Clarify slice and Vec iteration order

While already being inferable from the doc examples, it wasn't fully specified. This is the only logical way to do a slice iterator, so I think this should be uncontroversial. It also improves the `Vec::into_iter` example to better show the order and that the iterator returns owned values.
2022-05-23 07:43:49 +02:00
ajtribick
1a41a665cf Reverse condition in Vec::retain_mut doctest 2022-05-19 20:54:16 +02:00
Nilstrieb
4a2214885d Clarify slice and Vec iteration order
While already being inferable from the doc examples, it wasn't
fully specified. This is the only logical way to do a slice
iterator.
2022-05-16 19:29:45 +02:00
Scott McMurray
e76b3f3b5b Rename unsigned_offset_from to sub_ptr 2022-05-11 17:16:25 -07:00
Scott McMurray
89a18cb600 Add unsigned_offset_from on pointers
Like we have `add`/`sub` which are the `usize` version of `offset`, this adds the `usize` equivalent of `offset_from`.  Like how `.add(d)` replaced a whole bunch of `.offset(d as isize)`, you can see from the changes here that it's fairly common that code actually knows the order between the pointers and *wants* a `usize`, not an `isize`.

As a bonus, this can do `sub nuw`+`udiv exact`, rather than `sub`+`sdiv exact`, which can be optimized slightly better because it doesn't have to worry about negatives.  That's why the slice iterators weren't using `offset_from`, though I haven't updated that code in this PR because slices are so perf-critical that I'll do it as its own change.

This is an intrinsic, like `offset_from`, so that it can eventually be allowed in CTFE.  It also allows checking the extra safety condition -- see the test confirming that CTFE catches it if you pass the pointers in the wrong order.
2022-05-11 17:16:25 -07:00
León Orell Valerian Liehr
9d157ada35 Warn on unused doc(hidden) on trait impl items 2022-05-08 22:53:14 +02:00
bors
6b6c1ffacc Auto merge of #96596 - scottmcm:limited-calloc, r=Mark-Simulacrum
Tweak the vec-calloc runtime check to only apply to shortish-arrays

r? `@Mark-Simulacrum`

`@nbdd0121` pointed out in https://github.com/rust-lang/rust/pull/95362#issuecomment-1114085395 that LLVM currently doesn't constant-fold the `IsZero` check for long arrays, so that seems like a reasonable justification for limiting it.

It appears that it's based on length, not byte size, (https://godbolt.org/z/4s48Y81dP), so that's what I used in the PR.  Maybe it's a ["the number of inlining shall be three"](https://youtu.be/s4wnuiCwTGU?t=320) sort of situation.

Certainly there's more that could be done here -- that generated code that checks long arrays byte-by-byte is highly suboptimal, for example -- but this is an easy, low-risk tweak.
2022-05-02 09:05:22 +00:00
Scott McMurray
2830dbd64f Tweak the calloc optimization to only apply to shortish-arrays 2022-05-01 22:28:11 -07:00
Yuki Okushi
1785f1549c Rollup merge of #96222 - jmaargh:john-mark/clarify-from-raw-parts-docs, r=JohnTitor
Clarify docs for `from_raw_parts` on `Vec` and `String`

Closes #95427

Original safety explanation for `from_raw_parts` was unclear on safety for consuming a C string. This clarifies when doing so is safe.
2022-05-02 10:41:55 +09:00
bors
bf611439e3 Auto merge of #95362 - scottmcm:calloc-arrays, r=Mark-Simulacrum
Support arrays of zeros in Vec's __rust_alloc_zeroed optimization

I happened to notice in https://users.rust-lang.org/t/any-advantage-of-box-u64-16-16-16-over-vec-u64/73500/3?u=scottmcm that the calloc optimization wasn't applying to vectors-of-arrays, so here's the easy fix for that.
2022-05-01 00:50:46 +00:00
bors
f1d8a7d662 Auto merge of #96489 - shepmaster:revert-vec-from-array-ref, r=yaahc
Revert "impl From<&[T; N]> and From<&mut [T; N]> for Vec<T>"

This reverts commit 5dd702763a.
2022-04-29 14:39:14 +00:00
Paolo Barbolini
c126f7fc8b Add VecDeque::extend from vec::IntoIter and slice::Iter specializations 2022-04-28 06:13:54 +02:00
Jake Goulding
762bb1f506 Revert "impl From<&[T; N]> and From<&mut [T; N]> for Vec<T>"
This reverts commit 5dd702763a.
2022-04-27 15:56:29 -04:00
jmaargh
4dda047de3 Clarify docs for from_raw_parts
Original safety explanation for from_raw_parts was
unclear on safety for consuming a C string. This
clarifies when doing so is safe.
2022-04-19 21:12:55 +01:00
Nicholas Nethercote
9c59d04d55 Speed up Vec::clear().
Currently it just calls `truncate(0)`. `truncate()` is (a) not marked as
`#[inline]`, and (b) more general than needed for `clear()`.

This commit changes `clear()` to do the work itself. This modest change
was first proposed in rust-lang#74172, where the reviewer rejected it because
there was insufficient evidence that `Vec::clear()`'s performance
mattered enough to justify the change. Recent changes within rustc have
made `Vec::clear()` hot within `macro_parser.rs`, so the change is now
clearly worthwhile.

Although it doesn't show wins on CI perf runs, this seems to be because they
use PGO. But not all platforms currently use PGO. Also, local builds don't use
PGO, and `truncate` sometimes shows up in an over-represented fashion in local
profiles. So local profiling will be made easier by this change.

Note that this will also benefit `String::clear()`, because it just
calls `Vec::clear()`.

Finally, the commit removes the `vec-clear.rs` codegen test. It was
added in #52908. From before then until now, `Vec::clear()` just called
`Vec::truncate()` with a zero length. The body of Vec::truncate() has
changed a lot since then. Now that `Vec::clear()` is doing actual work
itself, and not just calling `Vec::truncate()`, it's not surprising that
its generated code includes a load and an icmp. I think it's reasonable
to remove this test.
2022-04-13 15:39:35 +10:00
Cyborus04
06788fd7a4 add <[[T; N]]>::flatten, <[[T; N]]>::flatten_mut, and Vec::<[T; N]>::into_flattened 2022-04-08 00:54:39 -04:00
Dylan DPC
c90a94707f Rollup merge of #95491 - faern:stabilize-vec_retain_mut, r=yaahc
Stabilize feature vec_retain_mut on Vec and VecDeque

Closes #90829
2022-03-31 04:57:27 +02:00
Dylan DPC
d6c959c680 Rollup merge of #95298 - jhorstmann:fix-double-drop-of-allocator-in-vec-into-iter, r=oli-obk
Fix double drop of allocator in IntoIter impl of Vec

Fixes #95269

The `drop` impl of `IntoIter` reconstructs a `RawVec` from `buf`, `cap` and `alloc`, when that `RawVec` is dropped it also drops the allocator. To avoid dropping the allocator twice we wrap it in `ManuallyDrop` in the `InttoIter` struct.

Note this is my first contribution to the standard library, so I might be missing some details or a better way to solve this.
2022-03-31 00:26:32 +02:00
Linus Färnstrand
796f385190 Stabilize feature vec_retain_mut on Vec and VecDeque 2022-03-30 20:28:50 +02:00
Aria Beingessner
c7de289e1c Make the stdlib largely conform to strict provenance.
Some things like the unwinders and system APIs are not fully conformant,
this only covers a lot of low-hanging fruit.
2022-03-29 20:18:21 -04:00
Dylan DPC
8bfc03fde0 Rollup merge of #95098 - shepmaster:vec-from-array-ref, r=dtolnay
impl From<&[T; N]> and From<&mut [T; N]> for Vec<T>

I really wanted to write:

```rust
fn example(a: impl Into<Vec<u8>>) {}

fn main() {
    example(b"raw");
}
```
2022-03-28 04:12:11 +02:00
Dylan DPC
d88c03c0f1 Rollup merge of #95016 - janpaul123:patch-1, r=dtolnay
Docs: make Vec::from_raw_parts documentation less strict

This is my first PR; be gentle!

In https://users.rust-lang.org/t/why-does-vec-from-raw-parts-require-same-size-and-not-same-size-capacity/73036/2?u=janpaul123 it was suggested to me that I should make a PR to make the documentation of `Vec::from_raw_parts` less strict, since we don't require `T` to have the same size, just `size_of::<T>() * capacity` to be the same, since that is what results in `Layout::size` being the same in `dealloc`, which is really what matters.

Also in https://users.rust-lang.org/t/why-does-vec-from-raw-parts-require-same-size-and-not-same-size-capacity/73036/8?u=janpaul123 it was suggested that it's better to use `slice::from_raw_parts`, which I think is useful advise that could also be mentioned in the docs, so I added that too.

Let me know what you think! :)
2022-03-28 04:12:10 +02:00
Dylan DPC
6ed1a67b38 Rollup merge of #93755 - ChayimFriedman2:allow-comparing-vecs-with-different-allocators, r=dtolnay
Allow comparing `Vec`s with different allocators using `==`

See https://stackoverflow.com/q/71021633/7884305.

I did not changed the `PartialOrd` impl too because it was not generic already (didn't support `Vec<T> <=> Vec<U> where T: PartialOrd<U>`).

Does it needs tests?

I don't think this will hurt type inference much because the default allocator is usually not inferred (`new()` specifies it directly, and even with other allocators, you pass the allocator to `new_in()` so the compiler usually knows the type).

I think this requires FCP since the impls are already stable.
2022-03-28 04:12:10 +02:00
Scott McMurray
8034c45a07 Support arrays of zeros in Vec's __rust_alloc_zeroed optimization 2022-03-27 01:50:07 -07:00
Jörn Horstmann
d14c0d2acb Use ManuallyDrop::take instead of into_inner
Co-authored-by: Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>
2022-03-25 13:27:18 +01:00
Jörn Horstmann
0cf606177e Fix double drop of allocator in IntoIter impl of Vec 2022-03-25 11:39:11 +01:00