This reverts PR <https://github.com/rust-lang/rust/pull/130998> because
the added test seems to be flaky / non-deterministic, and has been
failing in unrelated PRs during merge CI.
`Vec::push` in consts MVP
Example:
```rust
const X: &'static [u32] = {
let mut v = Vec::with_capacity(6);
let mut x = 1;
while x < 42 {
v.push(x);
x *= 2;
}
assert!(v.len() == 6);
v.const_make_global()
};
assert_eq!([1, 2, 4, 8, 16, 32], X);
```
Oh this is fun...
* We split out the implementation of `Global` such that it calls `intrinsics::const_allocate` and `intrinsics::const_deallocate` during compile time. This is achieved using `const_eval_select`
* This allows us to `impl const Allocator for Global`
* We then constify everything necessary for `Vec::with_capacity` and `Vec::push`.
* Added `Vec::const_make_global` to leak and intern the final value via `intrinsics::const_make_global`. If we see any pointer in the final value of a `const` that did not call `const_make_global`, we error as implemented in rust-lang/rust#143595.
r? `@rust-lang/wg-const-eval`
To-do for me:
* [x] Assess the rustdoc impact of additional bounds in the method
* [x] ~~Increase test coverage~~ I think this is enough for an unstable feature.
Improve alloc `Vec::retain_mut` performance
Hi,
While reading the rustc source code, I noticed it uses `smallvec` and `thin-vec` in many places. I started reviewing those crates, optimized their `retain_mut` implementation, and then realized they were using the exact same algorithm as `alloc::vec::Vec` with less unsafe So now I’m back here with a PR for the standard library 😂.
In my benchmarks, this version is noticeably faster when `retain_mut` actually removes elements (thanks to fewer pointer operations, it just advances `write_index`), while performing identically to the current implementation when nothing is removed.
Let’s see if bors likes this change or not.
alloc: Move Cow impl to existing ones
Right now, the `borrow.rs` module starts with a `Cow` impl, although most of them can be found below.
This hurts code readability because there is `ToOwned` alongside its impl directly below it.
Moving it to the others down below makes sense here, given that the entire enum depends on `ToOwned` anyways.
make specialization of `Vec::extend` and `VecDeque::extend_front` work for vec::IntoIter with any `Allocator`, not just `Global`
These functions consume all the elements from the respective collection, but do not care about the `Allocator` they use. Without specifying one (like in `vec::IntoIter<T>`) the specialization is only chosen when `A=Global`.
(extra context: `VecDeque::extend_front` is unstable and tracked by rust-lang/rust#146975)
Add specialization for `deque1.prepend(deque2.drain(range))` (VecDeque::prepend and extend_front)
Tracking issue: rust-lang/rust#146975
This specialization makes sure `deque1.prepend(deque2.drain(..))` gets similar speed to `deque1.append(&mut deque2)`. `deque1.prepend(deque2.drain(..))` is the equivalent of `deque1.append(&mut deque2)` but appending to the front (see the [second example of prepend](https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.prepend), prepend is from the same tracking issue).
Right now, the `borrow.rs` module starts with a `Cow` impl, although
most of them can be found below.
This hurts code readability because there is `ToOwned` alongside its
impl directly below it.
Moving it to the others down below makes sense here, given that the
entire enum depends on `ToOwned` anyways.
Fixes the sentence "Attempts to converts a Vec<u8> to a CString.", where "converts" should be in the base form as it is part of the to-infinitive form.
Cleanup linked list
- Replaces some checked_sub().unwrap_or(0) with saturating_sub().
- Replaces NonNull::from(Box::leak(node)) with Box::into_non_null(node)
alloc: specialize String::extend for slices of str
Here's a small optimization via specialization that can potentially eliminate a fair few reallocations when building strings using specific patterns, unsure if this justifies the use of unsafe, but I had the code implemented from rust-lang/rust#148604, so I thought it was worth submitting to see.
Fix `LinkedList::CursorMut::pop_front` to correctly update index
When `pop_front` was called while the cursor pointed to the front element, `move_next` incremented the index but it was never decremented afterwards, causing the index to incorrectly report 1 instead of 0.
Always decrement the index after popping from front using `saturating_sub` to handle edge cases safely.
Fixesrust-lang/rust#147616
When `pop_front` was called while the cursor pointed to the front
element, `move_next` incremented the index but it was never decremented
afterwards, causing the index to incorrectly report 1 instead of 0.
Always decrement the index after popping from front using
`saturating_sub` to handle edge cases safely.
Remove -Zoom=panic
There are major questions remaining about the reentrancy that this allows. It doesn't have any users on github outside of a single project that uses it in a panic=abort project to show backtraces. It can still be emulated through `#[alloc_error_handler]` or `set_alloc_error_hook` depending on if you use the standard library or not. And finally it makes it harder to do various improvements to the allocator shim.
With this PR the sole remaining symbol in the allocator shim that is not effectively emulating weak symbols is the symbol that prevents skipping the allocator shim on stable even when it would otherwise be empty because libstd + `#[global_allocator]` is used.
Closes https://github.com/rust-lang/rust/issues/43596
Fixes https://github.com/rust-lang/rust/issues/126683
This commit consolidates all changes, including the core logic fix for IntoIter::nth_back and the addition of the Miri regression test in `library/alloctests/tests/vec.rs`, to prevent Undefined Behavior (UB) when dealing with highly-aligned Zero-Sized Types.
alloc: Document panics when allocations will exceed max
Document panics in `String` and `Vec` due to capacity overflowing `isize::MAX`. Correct outdated claims of `usize::MAX` limit.
Fixes https://github.com/rust-lang/rust/issues/148598.
Ping `@lolbinarycat`
In `BTreeMap::eq`, do not compare the elements if the sizes are different.
Reverts rust-lang/rust#147101 in library/alloc/src/btree/
rust-lang/rust#147101 replaced some instances of code like `a.len() == b.len() && a.iter().eq(&b)` with just `a.iter().eq(&b)`, but the optimization that PR introduced only applies for `TrustedLen` iterators, and `BTreeMap`'s itertors are not `TrustedLen`, so this theoretically regressed perf for comparing large `BTreeMap`/`BTreeSet`s with unequal lengths but equal prefixes, (and also made it so that comparing two different-length `BTreeMap`/`BTreeSet`s with elements whose `PartialEq` impls that can panic now can panic, though this is not a "promised" behaviour either way (cc rust-lang/rust#149122))
Given that `TrustedLen` is an unsafe trait, I opted to not implement it for `BTreeMap`'s iterators, and instead just revert the change. If someone else wants to audit `BTreeMap`'s iterators to make sure they always return the right number of items (even in the face of incorrect user `Ord` impls) and then implement `TrustedLen` for them so that the optimization works for them, then this can be closed in favor of that (or if the perf regression is deemed too theoretical, this can be closed outright).
Example of theoretical perf regression: https://play.rust-lang.org/?version=beta&mode=release&edition=2024&gist=a37e3d61e6bf02669b251315c9a44fe2 (very rough estimates, using `Instant::elapsed`).
In release mode on stable the comparison takes ~23.68µs.
In release mode on beta/nightly the comparison takes ~48.351057ms.