Introduce `Rvalue::ShallowInitBox`
Polished version of #88700.
Implements MCP rust-lang/compiler-team#460, and should allow #43596 to go forward.
In short, creating an empty box is split from a nullary-op `NullOp::Box` into two steps, first a call to `exchange_malloc`, then a `Rvalue::ShallowInitBox` which transmutes `*mut u8` to a shallow-initialized `Box<T>`. This allows the `exchange_malloc` call to unwind. Details can be found in the MCP.
`NullOp::Box` is not yet removed, purely to make reverting easier in case anything goes wrong as the result of this PR. If revert is needed a reversion of "Use Rvalue::ShallowInitBox for box expression" commit followed by a test bless should be sufficient.
Experiments in #88700 showed a very slight compile-time perf regression due to (supposedly) slightly more time spent in LLVM. We could omit unwind edge generation (in non-`oom=panic` case) in box expression MIR construction to restore perf; but I don't think it's necessary since runtime perf isn't affected and perf difference is rather small.
Fix missing `no_global_oom_handling` cfg-gating
Cfg-gate these trait impls that are neglected.
These functions compile now because they use `box` syntax which depends on `exchange_malloc` during codegen only; as a result they compiles with cfg `no_global_oom_handling` but shouldn't.
Discovered in #89030 because that PR makes `box` syntax depend on `exchange_malloc` lang item during MIR construction.
BTreeMap/BTreeSet::from_iter: use bulk building to improve the performance
Bulk building is a common technique to increase the performance of building a fresh btree map. Instead of inserting items one-by-one, we sort all the items beforehand then create the BtreeMap in bulk.
Benchmark
```
./x.py bench library/alloc --test-args btree::map::from_iter
```
* Before
```
test btree::map::from_iter_rand_100 ... bench: 3,694 ns/iter (+/- 840)
test btree::map::from_iter_rand_10_000 ... bench: 1,033,446 ns/iter (+/- 192,950)
test btree::map::from_iter_seq_100 ... bench: 5,689 ns/iter (+/- 1,259)
test btree::map::from_iter_seq_10_000 ... bench: 861,033 ns/iter (+/- 118,815)
```
* After
```
test btree::map::from_iter_rand_100 ... bench: 3,033 ns/iter (+/- 707)
test btree::map::from_iter_rand_10_000 ... bench: 775,958 ns/iter (+/- 105,152)
test btree::map::from_iter_seq_100 ... bench: 2,969 ns/iter (+/- 336)
test btree::map::from_iter_seq_10_000 ... bench: 258,292 ns/iter (+/- 29,364)
```
BTree: remove Ord bound from new
`K: Ord` bound is unnecessary on `BTree{Map,Set}::new` and their `Default` impl. No elements exist so there are nothing to compare anyway, so I don't think "future proof" would be a blocker here. This is analogous to `HashMap::new` not having a `K: Eq + Hash` bound.
#79245 originally does this and for some reason drops the change to `new` and `Default`. I can see why changes to other methods like `entry` or `symmetric_difference` need to be careful but I couldn't find out any reason not to do it on `new`.
Removing the bound also makes the stabilisation of `const fn new` not depending on const trait bounds.
cc `@steffahn` who suggests me to make this PR.
r? `@dtolnay`
Bulk building is a common technique to increase the performance of
building a fresh btree map. Instead of inserting items one-by-one,
we sort all the items beforehand then create the BtreeMap in bulk.
Fix typo “a Rc” → “an Rc” (and a few more)
After stumbling about it in the dev-guide, I’ve devided to eliminate all mentions of “a Rc”, replacing it with “an Rc”. E.g.
```plain
$ rg "(^|[^'])\ba\b[^\w=:]*\bRc"
compiler/rustc_data_structures/src/owning_ref/mod.rs
1149:/// Typedef of a owning reference that uses a `Rc` as the owner.
library/std/src/ffi/os_str.rs
919: /// Converts a [`OsString`] into a [`Rc`]`<OsStr>` without copying or allocating.
library/std/src/ffi/c_str.rs
961: /// Converts a [`CString`] into a [`Rc`]`<CStr>` without copying or allocating.
src/doc/rustc-dev-guide/src/query.md
61:are cheaply cloneable; insert a `Rc` if necessary).
src/doc/book/src/ch15-06-reference-cycles.md
72:decreases the reference count of the `a` `Rc<List>` instance from 2 to 1 as
library/alloc/src/rc.rs
1746: /// Converts a generic type `T` into a `Rc<T>`
```
_(the match in the book is a false positive)_
Since the dev-guide is a submodule, it’s getting a separate PR: rust-lang/rustc-dev-guide#1191
I’ve also gone ahead and done the same search for `RwLock` and hit a few cases in the `OwningRef` adaption. Then, I couldn’t keep the countless cases of “a owning …” or “a owner” unaddressed, which concludes this PR.
`@rustbot` label C-cleanup
Adjust / fix documentation of `Arc::make_mut`
Related discussion in the users forum:
[Whatʼs this alleged difference between Arc::make_mut and Rc::make_mut? – The Rust Programming Language Forum](https://users.rust-lang.org/t/what-s-this-alleged-difference-between-arc-make-mut-and-rc-make-mut/63747?u=steffahn)
Also includes a small formatting improvement in the documentation of `Rc::make_mut`.
This PR makes the two documentations in question complete analogs. The previously claimed point in which one “differs from the behavior of” the other turns out to be incorrect, AFAIK.
One remaining inaccuracy: `Weak` pointers aren’t disassociated from the allocation but only from the contained value, i.e. in case of outstanding `Weak` pointers there still is a new allocation created, just the call to `.clone()` is avoided, instead the value is moved from one allocation to the other.
`@rustbot` label T-libs-api, A-docs
Optimize unnecessary check in VecDeque::retain
This pr is highly inspired by https://github.com/rust-lang/rust/pull/88060 which shared the same idea: we can split the `for` loop into stages so that we can remove unnecessary checks like `del > 0`.
## Benchmarks
Before
```rust
test collections::vec_deque::tests::bench_retain_half_10000 ... bench: 290,125 ns/iter (+/- 8,717)
test collections::vec_deque::tests::bench_retain_odd_10000 ... bench: 291,588 ns/iter (+/- 9,621)
test collections::vec_deque::tests::bench_retain_whole_10000 ... bench: 287,426 ns/iter (+/- 9,009)
```
After
```rust
test collections::vec_deque::tests::bench_retain_half_10000 ... bench: 243,940 ns/iter (+/- 8,563)
test collections::vec_deque::tests::bench_retain_odd_10000 ... bench: 242,768 ns/iter (+/- 3,903)
test collections::vec_deque::tests::bench_retain_whole_10000 ... bench: 202,926 ns/iter (+/- 6,332)
```
Based on the current benchmark, this PR will improve the perf of `VecDeque::retain` by around 16%. For special cases, the improvement will be up to 30%.
Signed-off-by: Xuanwo <github@xuanwo.io>
Related discussion in the users forum:
https://users.rust-lang.org/t/what-s-this-alleged-difference-between-arc-make-mut-and-rc-make-mut/63747?u=steffahn
Also includes small formatting improvement in the documentation of `Rc::make_mut`.
This commit makes the two documentations in question complete analogs. The previously claimed point in which
one "differs from the behavior of" the other turns out to be incorrect, AFAIK.
One remaining inaccuracy: `Weak` pointers aren't disassociated from the allocation but only from the contained
value, i.e. in case of outstanding `Weak` pointers there still is a new allocation created, just the
call to `.clone()` is avoided, instead the value is moved from one allocation to the other.