String::remove_matches O(n^2) -> O(n)
Copy only non-matching bytes. Replace collection of matches into a
vector with iteration over rejections, exploiting the guarantee that we
mutate parts of the haystack that have already been searched over.
r? `@joshtriplett`
Update standard library for IntoIterator implementation of arrays
This PR partially resolves issue #84513 of updating the standard library part.
I haven't found any remaining doctest examples which are using iterators over e.g. &i32 instead of just i32 in the standard library. Can anyone point me to them if there's remaining any?
Thanks!
r? ```@m-ou-se```
## User-facing changes
- Intra-doc links to primitives that currently go to rust-lang.org/nightly/std/primitive.x.html will start going to channel that rustdoc was built with. Nightly will continue going to /nightly; Beta will link to /beta; stable compilers will link to /1.52.1 (or whatever version they were built as).
- Cross-crate links from std to core currently go to /nightly unconditionally. They will start going to /1.52.0 on stable channels (but remain the same on nightly channels).
- Intra-crate links from std to std (or core to core) currently go to the same URL they are hosted at; they will continue to do so. Notably, this is different from everything else because it can preserve the distinction between /stable and /1.52.0 by using relative links.
Note that "links" includes both intra-doc links and rustdoc's own
automatically generated hyperlinks.
## Implementation changes
- Update the testsuite to allow linking to /beta and /1.52.1 in docs
- Use an html_root_url for the standard library that's dependent on the channel
This avoids linking to nightly docs on stable.
- Update rustdoc to use channel-dependent links for primitives from an
unknown crate
- Set DOC_RUST_LANG_ORG_CHANNEL from bootstrap to ensure it's in sync
- Include doc.rust-lang.org in the channel
Add `String::extend_from_within`
This PR adds `String::extend_from_within` function under the `string_extend_from_within` feature gate similar to the [`Vec::extend_from_within`] function.
```rust
// String
pub fn extend_from_within<R>(&mut self, src: R)
where
R: RangeBounds<usize>;
```
[`Vec::extend_from_within`]: https://github.com/rust-lang/rust/issues/81656
This patch adds `String::extend_from_within` function under the
`string_extend_from_within` feature gate similar to the
`Vec::extend_from_within` function.
Due to a performance regression that didn't show up in the original perf run
this reverts commit 9111b8ae9793f18179a1336417618fc07a9cac85, reversing
changes made to 9a700d2947f2d7f97a2c0dfca3117a8dcc255bdd.
Enable Vec's calloc optimization for Option<NonZero>
Someone on discord noticed that `vec![None::<NonZeroU32>; N]` wasn't getting the optimization, so here's a PR 🙃
We can certainly do this in the standard library because we know for sure this is ok, but I think it's also a necessary consequence of documented guarantees like those in https://doc.rust-lang.org/std/option/#representation and https://doc.rust-lang.org/core/num/struct.NonZeroU32.html
It feels weird to do this without adding a test, but I wasn't sure where that would belong. Is it worth adding codegen tests for these?
Add `TrustedRandomAccess` specialization for `Vec::extend()`
This should do roughly the same as the `TrustedLen` specialization but result in less IR by using `__iterator_get_unchecked`
instead of `Iterator::for_each`
Conflicting specializations are manually prioritized by grouping them under yet another helper trait.
Weak's type parameter may dangle on drop
Way back in 34076bc0c9, #\[may_dangle\] was added to Rc\<T\> and Arc\<T\>'s Drop impls. That appears to have been because a test added in #28929 used Arc and Rc with dangling references at drop time. However, Weak was not covered by that test, and therefore no #\[may_dangle\] was forced to be added at the time.
As far as dropping, Weak has *even less need* to interact with the T than Rc and Arc do. Roughly speaking #\[may_dangle\] describes generic parameters that the outer type's Drop impl does not interact with except by possibly dropping them; no other interaction (such as trait method calls on the generic type) is permissible. It's clear this applies to Rc's and Arc's drop impl, which sometimes drop T but otherwise do not interact with one. It applies *even more* to Weak. Dropping a Weak cannot ever cause T's drop impl to run. Either there are strong references still in existence, in which case better not drop the T. Or there are no strong references still in existence, in which case the T would already have been dropped previously by the drop of the last strong count.
Avoid zero-length memcpy in formatting
This has two separate and somewhat orthogonal commits. The first change adjusts the ToString general impl for all types that implement Display; it no longer uses the full format machinery, rather directly falling onto a `std::fmt::Display::fmt` call. The second change directly adjusts the general core::fmt::write function which handles the production of format_args! to avoid zero-length push_str calls.
Both changes target the fact that push_str will still call memmove internally (or a similar function), as it doesn't know the length of the passed string. For zero-length strings in particular, this is quite expensive, and even for very short (several bytes long) strings, this is also expensive. Future work in this area may wish to have us fallback to write_char or similar, which may be cheaper on the (typically) short strings between the interpolated pieces in format_args!.
This also checks the contents and not only the capacity in case IntoIter's clone implementation is changed to add capacity at the end. Extra capacity at the beginning would be needed to make InPlaceIterable work.
Co-authored-by: Giacomo Stevanato <giaco.stevanato@gmail.com>
The unsoundness is not in Peekable per se, it rather is due to the
interaction between Peekable being able to hold an extra item
and vec::IntoIter's clone implementation shortening the allocation.
An alternative solution would be to change IntoIter's clone implementation
to keep enough spare capacity available.
Implement the new desugaring from `try_trait_v2`
~~Currently blocked on https://github.com/rust-lang/rust/issues/84782, which has a PR in https://github.com/rust-lang/rust/pull/84811~~ Rebased atop that fix.
`try_trait_v2` tracking issue: https://github.com/rust-lang/rust/issues/84277
Unfortunately this is already touching a ton of things, so if you have suggestions for good ways to split it up, I'd be happy to hear them. (The combination between the use in the library, the compiler changes, the corresponding diagnostic differences, even MIR tests mean that I don't really have a great plan for it other than trying to have decently-readable commits.
r? `@ghost`
~~(This probably shouldn't go in during the last week before the fork anyway.)~~ Fork happened.
This avoids a zero-length write_str call, which boils down to a zero-length
memmove and ultimately costs quite a few instructions on some workloads.
This is approximately a 0.33% instruction count win on diesel-check.
BTree: no longer copy keys and values before dropping them
When dropping BTreeMap or BTreeSet instances, keys-value pairs are up to now each copied and then dropped, at least according to source code. This is because the code for dropping and for iterators is shared.
This PR postpones the treatment of doomed key-value pairs from the intermediate functions `deallocating_next`(`_back`) to the last minute, so the we can drop the keys and values in place. According to the library/alloc benchmarks, this does make a difference, (and a positive difference with an `#[inline]` on `drop_key_val`). It does not change anything for #81444 though.
r? `@Mark-Simulacrum`