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.
Make Vec::split_at_spare_mut public
This PR introduces a new method to the public API, under
`vec_split_at_spare` feature gate:
```rust
impl<T, A: Allocator> impl Vec<T, A> {
pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]);
}
```
The method returns 2 slices, one slice references the content of the vector,
and the other references the remaining spare capacity.
The method was previously implemented while adding `Vec::extend_from_within` in #79015,
and used to implement `Vec::spare_capacity_mut` (as the later is just a
subset of former one).
See also previous [discussion in `Vec::spare_capacity_mut` tracking issue](https://github.com/rust-lang/rust/issues/75017#issuecomment-770381335).
## Unresolved questions
- [ ] Should we consider changing the name? `split_at_spare_mut` doesn't seem like an intuitive name
- [ ] Should we deprecate `Vec::spare_capacity_mut`? Any usecase of `Vec::spare_capacity_mut` can be replaced with `Vec::split_at_spare_mut` (but not vise-versa)
r? `@KodrAus`
Add `Box::into_inner`.
This adds a `Box::into_inner` method to the `Box` type. <del>I actually suggest deprecating the compiler magic of `*b` if this gets stablized in the future.</del>
r? `@m-ou-se`
Rollup of 11 pull requests
Successful merges:
- #72209 (Add checking for no_mangle to unsafe_code lint)
- #80732 (Allow Trait inheritance with cycles on associated types take 2)
- #81697 (Add "every" as a doc alias for "all".)
- #81826 (Prefer match over combinators to make some Box methods inlineable)
- #81834 (Resolve typedef in HashMap lldb pretty-printer only if possible)
- #81841 ([rustbuild] Output rustdoc-json-types docs )
- #81849 (Expand the docs for ops::ControlFlow a bit)
- #81876 (parser: Fix panic in 'const impl' recovery)
- #81882 (⬆️ rust-analyzer)
- #81888 (Fix pretty printer macro_rules with semicolon.)
- #81896 (Remove outdated comment in windows' mutex.rs)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Prefer match over combinators to make some Box methods inlineable
Hopefully this patch would make two snippets generated identical code: <https://rust.godbolt.org/z/fjrj4E>.
BTree: remove Ord bound where it is absent elsewhere
Some btree methods don't really need an Ord bound and don't have one, while some methods that more obviously don't need it, do have one.
An example of the former is `iter`, even though it explicitly exposes the work of the Ord implementation (["sorted by key"](https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#method.iter) - but I'm not suggesting it should have the Ord bound). An example of the latter is `new`, which doesn't involve any keys whatsoever.
BTreeMap: make Ord bound explicit, compile-test its absence
Most `BTreeMap` and `BTreeSet` members are subject to an `Ord` bound but a fair number of methods are not. To better convey and perhaps later tune the `Ord` bound, make it stand out in individual `where` clauses, instead of once far away at the beginning of an `impl` block. This PR does not introduce or remove any bounds.
Also adds compilation test cases checking that the bound doesn't creep in unintended on the historically unbounded methods.
This commit introduces a new method to the public API, under
`vec_split_at_spare` feature gate:
```rust
impl<T, A: Allocator> impl Vec<T, A> {
pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>]);
}
```
The method returns 2 slices, one slice references the content of the vector,
and the other references the remaining spare capacity.
The method was previously implemented while adding `Vec::extend_from_within`,
and used to implement `Vec::spare_capacity_mut` (as the later is just a
subset of former one).
Add doc aliases for "delete"
This patch adds doc aliases for "delete". The added aliases are supposed to reference usages `delete` in other programming languages.
- `HashMap::remove`, `BTreeMap::remove` -> `Map#delete` and `delete` keyword in JavaScript.
- `HashSet::remove`, `BTreeSet::remove` -> `Set#delete` in JavaScript.
- `mem::drop` -> `delete` keyword in C++.
- `fs::remove_file`, `fs::remove_dir`, `fs::remove_dir_all`-> `File#delete` in Java, `File#delete` and `Dir#delete` in Ruby.
Before this change, searching for "delete" in documentation returned no results.
add `Vec::extend_from_within` method under `vec_extend_from_within` feature gate
Implement <https://github.com/rust-lang/rfcs/pull/2714>
### tl;dr
This PR adds a `extend_from_within` method to `Vec` which allows copying elements from a range to the end:
```rust
#![feature(vec_extend_from_within)]
let mut vec = vec![0, 1, 2, 3, 4];
vec.extend_from_within(2..);
assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
vec.extend_from_within(..2);
assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
vec.extend_from_within(4..8);
assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
```
### Implementation notes
Originally I've copied `@Shnatsel's` [implementation](690742a0de/src/lib.rs (L74)) with some minor changes to support other ranges:
```rust
pub fn append_from_within<R>(&mut self, src: R)
where
T: Copy,
R: RangeBounds<usize>,
{
let len = self.len();
let Range { start, end } = src.assert_len(len);;
let count = end - start;
self.reserve(count);
unsafe {
// This is safe because `reserve()` above succeeded,
// so `self.len() + count` did not overflow usize
ptr::copy_nonoverlapping(
self.get_unchecked(src.start),
self.as_mut_ptr().add(len),
count,
);
self.set_len(len + count);
}
}
```
But then I've realized that this duplicates most of the code from (private) `Vec::append_elements`, so I've used it instead.
Then I've applied `@KodrAus` suggestions from https://github.com/rust-lang/rust/pull/79015#issuecomment-727200852.
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()`).
Remove const_in_array_repeat
Fixes#80371. Fixes#81315. Fixes#80767. Fixes#75682.
I thought there might be some issue with `Repeats(_, 0)`, but if you increase the items in the array it still ICEs. I'm not sure if this is the best fix but it does fix the given issue.
This patch adds doc aliases for "delete". The added aliases are
supposed to reference usages `delete` in other programming
languages.
- `HashMap::remove`, `BTreeMap::remove` -> `Map#delete` and `delete`
keyword in JavaScript.
- `HashSet::remove`, `BTreeSet::remove` -> `Set#delete` in JavaScript.
- `mem::drop` -> `delete` keyword in C++.
- `fs::remove_file`, `fs::remove_dir`, `fs::remove_dir_all`
-> `File#delete` in Java, `File#delete` and `Dir#delete` in Ruby.
Before this change, searching for "delete" in documentation
returned no results.
Stabilize by-value `[T; N]` iterator `core::array::IntoIter`
Tracking issue: https://github.com/rust-lang/rust/issues/65798
This is unblocked now that `min_const_generics` has been stabilized in https://github.com/rust-lang/rust/pull/79135.
This PR does *not* include the corresponding `IntoIterator` impl, which is https://github.com/rust-lang/rust/pull/65819. Instead, an iterator can be constructed through the `new` method.
`new` would become unnecessary when `IntoIterator` is implemented and might be deprecated then, although it will stay stable.
Stabilize raw ref macros
This stabilizes `raw_ref_macros` (https://github.com/rust-lang/rust/issues/73394), which is possible now that https://github.com/rust-lang/rust/issues/74355 is fixed.
However, as I already said in https://github.com/rust-lang/rust/issues/73394#issuecomment-751342185, I am not particularly happy with the current names of the macros. So I propose we also change them, which means I am proposing to stabilize the following in `core::ptr`:
```rust
pub macro const_addr_of($e:expr) {
&raw const $e
}
pub macro mut_addr_of($e:expr) {
&raw mut $e
}
```
The macro name change means we need another round of FCP. Cc `````@rust-lang/libs`````
Fixes#73394
Add `core::stream::Stream`
[[Tracking issue: #79024](https://github.com/rust-lang/rust/issues/79024)]
This patch adds the `core::stream` submodule and implements `core::stream::Stream` in accordance with [RFC2996](https://github.com/rust-lang/rfcs/pull/2996). The RFC hasn't been merged yet, but as requested by the libs team in https://github.com/rust-lang/rfcs/pull/2996#issuecomment-725696389 I'm filing this PR to get the ball rolling.
## Documentatation
The docs in this PR have been adapted from [`std::iter`](https://doc.rust-lang.org/std/iter/index.html), [`async_std::stream`](https://docs.rs/async-std/1.7.0/async_std/stream/index.html), and [`futures::stream::Stream`](https://docs.rs/futures/0.3.8/futures/stream/trait.Stream.html). Once this PR lands my plan is to follow this up with PRs to add helper methods such as `stream::repeat` which can be used to document more of the concepts that are currently missing. That will allow us to cover concepts such as "infinite streams" and "laziness" in more depth.
## Feature gate
The feature gate for `Stream` is `stream_trait`. This matches the `#[lang = "future_trait"]` attribute name. The intention is that only the APIs defined in RFC2996 will use this feature gate, with future additions such as `stream::repeat` using their own feature gates. This is so we can ensure a smooth path towards stabilizing the `Stream` trait without needing to stabilize all the APIs in `core::stream` at once. But also don't start expanding the API until _after_ stabilization, as was the case with `std::future`.
__edit:__ the feature gate has been changed to `async_stream` to match the feature gate proposed in the RFC.
## Conclusion
This PR introduces `core::stream::{Stream, Next}` and re-exports it from `std` as `std::stream::{Stream, Next}`. Landing `Stream` in the stdlib has been a mult-year process; and it's incredibly exciting for this to finally happen!
---
r? `````@KodrAus`````
cc/ `````@rust-lang/wg-async-foundations````` `````@rust-lang/libs`````
BTreeMap: prevent tree from ever being owned by non-root node
This introduces a new marker type, `Dying`, which is used to note trees which are in the process of deallocation. On such trees, some fields may be in an inconsistent state as we are deallocating the tree. Unfortunately, there's not a great way to express conditional unsafety, so the methods for traversal can cause UB if not invoked correctly, but not marked as such. This is not a regression from the previous state, but rather isolates the destructive methods to solely being called on the dying state.
Trying to shrink_to greater than capacity should be no-op
Per the discussion in https://github.com/rust-lang/rust/issues/56431, `shrink_to` shouldn't panic if you try to make a vector shrink to a capacity greater than its current capacity.
BTreeMap: test all borrowing interfaces and test more chaotic order behavior
Inspired by #81169, test what happens if you mess up order of the type with which you search (as opposed to the key type).
r? `@Mark-Simulacrum`
BTreeMap: bring back the key slice for immutable lookup
Pave the way for binary search, by reverting a bit of #73971, which banned `keys` for misbehaving while it was defined for every `BorrowType`. Adding some `debug_assert`s along the way.
r? `@Mark-Simulacrum`