| Age | Commit message (Collapse) | Author | Lines |
|
|
|
Switch Vec from doubling size on growth to using RawVec's reserve
On growth, Vec does not require to exactly double its size for correctness,
like, for example, VecDeque does.
Using reserve instead better expresses this intent. It also allows to reuse
Excess capacity on growth and for better growth-policies to be provided by
RawVec.
r? @sfackler
|
|
|
|
Switch to bootstrapping from 1.27
It's possible the Float trait could be removed from core, but I couldn't tell whether it was intended to be removed or not. @SimonSapin may be able to comment more here; we can presumably also do that in a follow up PR as this one is already quite large.
|
|
|
|
|
|
Implement From for more types on Cow
This is basically https://github.com/rust-lang/rust/pull/48191, except that it should be implemented in a way that doesn't break third party crates.
|
|
Tracking issue: https://github.com/rust-lang/rust/issues/49137
|
|
On growth, Vec does not require to exactly double its size for correctness,
like, for example, VecDeque does.
Using reserve instead better expresses this intent. It also allows to reuse
Excess capacity on growth and for better growth-policies to be provided by
RawVec.
|
|
Don't allocate when creating an empty BTree
Following the discussion in #50266, this adds a static instance of `LeafNode` that empty BTrees point to, and then replaces it on `insert`, `append`, and `entry`. This avoids allocating for empty maps.
Fixes #50266
r? @Gankro
|
|
Attempting to fix https://travis-ci.org/rust-lang/rust/jobs/377407894 via some
selective ignoring tests
|
|
Restore RawVec::reserve* documentation
When the RawVec::try_reserve* methods were added, they took the place of
the ::reserve* methods in the source file, and new ::reserve* methods
wrapping the new try_reserve* methods were created. But the
documentation didn't move along, such that:
- reserve_* methods are barely documented.
- try_reserve_* methods have unmodified documentation from reserve_*,
such that their documentation indicate they are panicking/aborting.
This moves the documentation back to the right methods, with a
placeholder documentation for the try_reserve* methods.
|
|
Move "See also" disambiguation links for primitive types to top
Closes #50384.
<details>
<summary>Images</summary>


</details>
r? @steveklabnik
|
|
std: Avoid `ptr::copy` if unnecessary in `vec::Drain`
This commit is spawned out of a performance regression investigation in #50496.
In tracking down this regression it turned out that the `expand_statements`
function in the compiler was taking quite a long time. Further investigation
showed two key properties:
* The function was "fast" on glibc 2.24 and slow on glibc 2.23
* The hottest function was memmove from glibc
Combined together it looked like glibc gained an optimization to the memmove
function in 2.24. Ideally we don't want to rely on this optimization, so I
wanted to dig further to see what was happening.
The hottest part of `expand_statements` was `Drop for Drain` in the call to
`splice` where we insert new statements into the original vector. This *should*
be a cheap operation because we're draining and replacing iterators of the exact
same length, but under the hood memmove was being called a lot, causing a
slowdown on glibc 2.23.
It turns out that at least one of the optimizations in glibc 2.24 was that
`memmove` where the src/dst are equal becomes much faster. [This program][prog]
executes in ~2.5s against glibc 2.23 and ~0.3s against glibc 2.24, exhibiting
how glibc 2.24 is optimizing `memmove` if the src/dst are equal.
And all that brings us to what this commit itself is doing. The change here is
purely to `Drop for Drain` to avoid the call to `ptr::copy` if the region being
copied doesn't actually need to be copied. For normal usage of just `Drain`
itself this check isn't really necessary, but because `Splice` internally
contains `Drain` this provides a nice speed boost on glibc 2.23. Overall this
should fix the regression seen in #50496 on glibc 2.23 and also fix the
regression on Windows where `memmove` looks to not have this optimization.
Note that the way `splice` was called in `expand_statements` would cause a
quadratic number of elements to be copied via `memmove` which is likely why the
tuple-stress benchmark showed such a severe regression.
Closes #50496
[prog]: https://gist.github.com/alexcrichton/c05bc51c6771bba5ae5b57561a6c1cd3
|
|
Give SliceIndex impls a test suite of girth befitting the implementation (and fix a UTF8 boundary check)
So one day I was writing something in my codebase that basically amounted to `impl SliceIndex for (Bound<usize>, Bound<usize>)`, and I said to myself:
*Boy, gee, golly! I never realized bounds checking was so tricky!*
At some point when I had around 60 lines of tests for it, I decided to go see how the standard library does it to see if I missed any edge cases. ...That's when I discovered that libcore only had about 40 lines of tests for slicing altogether, and none of them even used `..=`.
---
This PR includes:
* **Literally the first appearance of the word `get_unchecked_mut` in any directory named `test` or `tests`.**
* Likewise the first appearance of `get_mut` used with _any type of range argument_ in these directories.
* Tests for the panics on overflow with `..=`.
* I wanted to test on `[(); usize::MAX]` as well but that takes linear time in debug mode </3
* A horrible and ugly test-generating macro for the `should_panic` tests that increases the DRYness by a single order of magnitude (which IMO wasn't enough, but I didn't want to go any further and risk making the tests inaccessible to next guy).
* Same stuff for str!
* Actually, the existing `str` tests were pretty good. I just helped filled in the holes.
* [A fix for the bug it caught](https://github.com/rust-lang/rust/issues/50002). (only one ~~sadly~~)
|
|
When the RawVec::try_reserve* methods were added, they took the place of
the ::reserve* methods in the source file, and new ::reserve* methods
wrapping the new try_reserve* methods were created. But the
documentation didn't move along, such that:
- reserve_* methods are barely documented.
- try_reserve_* methods have unmodified documentation from reserve_*,
such that their documentation indicate they are panicking/aborting.
This moves the documentation back to the right methods, with a
placeholder documentation for the try_reserve* methods.
|
|
|
|
This commit is spawned out of a performance regression investigation in #50496.
In tracking down this regression it turned out that the `expand_statements`
function in the compiler was taking quite a long time. Further investigation
showed two key properties:
* The function was "fast" on glibc 2.24 and slow on glibc 2.23
* The hottest function was memmove from glibc
Combined together it looked like glibc gained an optimization to the memmove
function in 2.24. Ideally we don't want to rely on this optimization, so I
wanted to dig further to see what was happening.
The hottest part of `expand_statements` was `Drop for Drain` in the call to
`splice` where we insert new statements into the original vector. This *should*
be a cheap operation because we're draining and replacing iterators of the exact
same length, but under the hood memmove was being called a lot, causing a
slowdown on glibc 2.23.
It turns out that at least one of the optimizations in glibc 2.24 was that
`memmove` where the src/dst are equal becomes much faster. [This program][prog]
executes in ~2.5s against glibc 2.23 and ~0.3s against glibc 2.24, exhibiting
how glibc 2.24 is optimizing `memmove` if the src/dst are equal.
And all that brings us to what this commit itself is doing. The change here is
purely to `Drop for Drain` to avoid the call to `ptr::copy` if the region being
copied doesn't actually need to be copied. For normal usage of just `Drain`
itself this check isn't really necessary, but because `Splice` internally
contains `Drain` this provides a nice speed boost on glibc 2.23. Overall this
should fix the regression seen in #50496 on glibc 2.23 and also fix the
regression on Windows where `memmove` looks to not have this optimization.
Note that the way `splice` was called in `expand_statements` would cause a
quadratic number of elements to be copied via `memmove` which is likely why the
tuple-stress benchmark showed such a severe regression.
Closes #50496
[prog]: https://gist.github.com/alexcrichton/c05bc51c6771bba5ae5b57561a6c1cd3
|
|
Cleanup a `use` in a raw_vec test
`allocator` is deprecated in favor of `alloc`, and `Alloc` is already imported
through `super::*`.
|
|
Add some explanations for #[must_use]
`#[must_use]` can be given a string argument which is shown whilst warning for things.
We should add a string argument to most of the user-exposed ones.
I added these for everything but the operators, mostly because I'm not sure what to write there or if we need anything there.
|
|
Make `String::new()` const
Following the steps of https://github.com/rust-lang/rust/pull/50233 , make `String::new()` a `const fn`.
|
|
|
|
Also remove some unnecessary debug_assert! when creating the shared
root, since the root should be stored in the rodata and thus be
impossible to accidentally modify.
|
|
Rename Pin to PinMut, and some more breaking changes
As discussed at [1] §3 and [2] and [3], a formal look at pinning requires considering a distinguished "shared pinned" mode/typestate. Given that, it seems desirable to at least eventually actually expose that typestate as a reference type. This renames Pin to PinMut, freeing the name Pin in case we want to use it for a shared pinned reference later on.
[1] https://www.ralfj.de/blog/2018/04/10/safe-intrusive-collections-with-pinning.html
[2] https://github.com/rust-lang/rfcs/pull/2349#issuecomment-379250361
[3] https://github.com/rust-lang/rust/issues/49150#issuecomment-380488275
Cc @withoutboats
|
|
`allocator` is deprecated in favor of `alloc`, and `Alloc` is already imported
through `super::*`.
|
|
|
|
|
|
This splits into_slices() into into_key_slice() and into_val_slice(). While the
extra calls would get optimized out, this is a useful semantic change since we
call keys() while iterating, and we don't want to construct and out-of-bounds
val() pointer in the process if we happen to be pointing to the shared static
root.
This also paves the way for doing the alignment handling conditional differently
for the keys and values.
|
|
We modify the drop implementation in IntoIter to not drop the shared root
|
|
This gives a pointer to that static empty node instead of allocating
a new node, and then whenever inserting makes sure that the root
isn't that empty node.
|
|
This way we can safely statically allocate a LeafNode to use as the
placeholder before allocating, and any type accessing it will be able to
access the metadata at the same offset.
|
|
|
|
As discussed at [1] §3 and [2] and [3], a formal look at pinning requires considering a
distinguished "shared pinned" mode/typestate. Given that, it seems desirable to
at least eventually actually expose that typestate as a reference type. This
renames Pin to PinMut, freeing the name Pin in case we want to use it for a
shared pinned reference later on.
[1] https://www.ralfj.de/blog/2018/04/10/safe-intrusive-collections-with-pinning.html
[2] https://github.com/rust-lang/rfcs/pull/2349#issuecomment-379250361
[3] https://github.com/rust-lang/rust/issues/49150#issuecomment-380488275
|
|
The Option is always Some until drop, where it becomes None. Make
this more explicit and avoid unwraps by using ManuallyDrop.
This change should be performance-neutral as LLVM already optimizes
the unwraps away in the inlined code.
|
|
|
|
Introduce RangeInclusive::{new, start, end} methods and make the fields private.
cc #49022
|
|
stabilize `#[must_use]` for functions and must-use comparison operators (RFC 1940)
r? @nikomatsakis
|
|
Make `Vec::new` a `const fn`
`RawVec::empty/_in` are a hack. They're there because `if size_of::<T> == 0 { !0 } else { 0 }` is not allowed in `const` yet. However, because `RawVec` is unstable, the `empty/empty_in` constructors can be removed when #49146 is done...
|
|
|
|
Added new()/start()/end() methods to RangeInclusive.
Changed the lowering of `..=` to use RangeInclusive::new().
|
|
|
|
m*n lines of implementation deserves m*n lines of tests
|
|
GitHub users: I think you can add ?w=1 to the url
for a vastly cleaner whitespace-ignoring diff
|
|
|
|
|
|
This is in the matter of RFC 1940 and tracking issue #43302.
|
|
|
|
std: Mark `ptr::Unique` with `#[doc(hidden)]`
`Unique` is now perma-unstable, so let's hide its docs.
|
|
Partial future-proofing for Box<T, A>
In some ways, this is similar to @eddyb's PR #47043 that went stale, but doesn't cover everything. Notably, this still leaves Box internalized as a pointer in places, so practically speaking, only ZSTs can be practically added to the Box type with the changes here (the compiler ICEs otherwise).
The Box type is not changed here, that's left for the future because I want to test that further first, but this puts things in place in a way that hopefully will make things easier.
|
|
|