Drop guards in slice sorting derive src pointers from &mut T, which is invalidated by interior mutation in comparison
I tried to run https://github.com/rust-lang/miri-test-libstd on `alloc` with `-Zmiri-track-raw-pointers`, and got a failure on the test `slice::panic_safe`. The test failure has nothing to do with panic safety, it's from how the test tests for panic safety.
I minimized the test failure into this very silly program:
```rust
use std::cell::Cell;
use std::cmp::Ordering;
#[derive(Clone)]
struct Evil(Cell<usize>);
fn main() {
let mut input = vec![Evil(Cell::new(0)); 3];
// Hits the bug pattern via CopyOnDrop in core
input.sort_unstable_by(|a, _b| {
a.0.set(0);
Ordering::Less
});
// Hits the bug pattern via InsertionHole in alloc
input.sort_by(|_a, b| {
b.0.set(0);
Ordering::Less
});
}
```
To fix this, I'm just removing the mutability/uniqueness where it wasn't required.
Rollup of 7 pull requests
Successful merges:
- #91587 (core::ops::unsize: improve docs for DispatchFromDyn)
- #91907 (Allow `_` as the length of array types and repeat expressions)
- #92515 (RustWrapper: adapt for an LLVM API change)
- #92516 (Do not use deprecated -Zsymbol-mangling-version in bootstrap)
- #92530 (Move `contains` method of Option and Result lower in docs)
- #92546 (Update books)
- #92551 (rename StackPopClean::None to Root)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Move `contains` method of Option and Result lower in docs
Follow-up to #92444 trying to get the `Option` and `Result` rustdocs in better shape.
This addresses the request in https://github.com/rust-lang/rust/issues/62358#issuecomment-645676285. The `contains` methods are previously too high up in the docs on both `Option` and `Result` — stuff like `ok` and `map` and `and_then` should all be featured higher than `contains`. All of those are more ubiquitously useful than `contains`.
- Do not `#[doc(hidden)]` the `#[derive]` macro attribute
- Add a link to the reference section to `derive`'s inherent docs
- Do the same for `#[test]` and `#[global_allocator]`
- Fix `GlobalAlloc` link (why is it on `core` and not `alloc`?)
- Try `no_inline`-ing the `std` reexports from `core`
- Revert "Try `no_inline`-ing the `std` reexports from `core`"
- Address PR review
- Also document the unstable macros
Consolidate Result's and Option's methods into fewer impl blocks
`Result`'s and `Option`'s methods have historically been separated up into `impl` blocks based on their trait bounds, with the bounds specified on type parameters of the impl block. I find this unhelpful because closely related methods, like `unwrap_or` and `unwrap_or_default`, end up disproportionately far apart in source code and rustdocs:
<pre>
impl<T> Option<T> {
pub fn unwrap_or(self, default: T) -> T {
...
}
<img alt="one eternity later" src="https://user-images.githubusercontent.com/1940490/147780325-ad4e01a4-c971-436e-bdf4-e755f2d35f15.jpg" width="750">
}
impl<T: Default> Option<T> {
pub fn unwrap_or_default(self) -> T {
...
}
}
</pre>
I'd prefer for method to be in as few impl blocks as possible, with the most logical grouping within each impl block. Any bounds needed can be written as `where` clauses on the method instead:
```rust
impl<T> Option<T> {
pub fn unwrap_or(self, default: T) -> T {
...
}
pub fn unwrap_or_default(self) -> T
where
T: Default,
{
...
}
}
```
*Warning: the end-to-end diff of this PR is computed confusingly by git / rendered confusingly by GitHub; it's practically impossible to review that way. I've broken the PR into commits that move small groups of methods for which git behaves better — these each should be easily individually reviewable.*
Track caller of slice split and swap
Improves error location for `slice.split_at*()` and `slice.swap()`.
These are generic inline functions, so the `#[track_caller]` on them is free — only changes a value of an argument already passed to panicking code.
Add `#[inline]` modifier to `TypeId::of`
It was already inlined but it happened only in 4th InlinerPass on my testcase.
With `#[inline]` modifier it happens on 2nd pass.
Closes#74362
disable test with self-referential generator on Miri
Running the libcore test suite in Miri currently fails due to the known incompatibility of self-referential generators with Miri's aliasing checks (https://github.com/rust-lang/unsafe-code-guidelines/issues/148). So let's disable that test in Miri for now.
Use panic() instead of panic!() in some places in core.
See https://github.com/rust-lang/rust/pull/92068 and https://github.com/rust-lang/rust/pull/92140.
This avoids the `panic!()` macro in a few potentially hot paths. This becomes more relevant when switching `core` to Rust 2021, as it'll avoid format_args!() and save some compilation time. (It doesn't make a huge difference, but still.) (Also the errors in const panic become slightly nicer.)
Allow reverse iteration of lowercase'd/uppercase'd chars
The PR implements `DoubleEndedIterator` trait for `ToLowercase` and `ToUppercase`.
This enables reverse iteration of lowercase/uppercase variants of character sequences.
One of use cases: determining whether a char sequence is a suffix of another one.
Example:
```rust
fn endswith_ignore_case(s1: &str, s2: &str) -> bool {
for eob in s1
.chars()
.flat_map(|c| c.to_lowercase())
.rev()
.zip_longest(s2.chars().flat_map(|c| c.to_lowercase()).rev())
{
match eob {
EitherOrBoth::Both(c1, c2) => {
if c1 != c2 {
return false;
}
}
EitherOrBoth::Left(_) => return true,
EitherOrBoth::Right(_) => return false,
}
}
true
}
```
Revert "Temporarily rename int_roundings functions to avoid conflicts"
This reverts commit 3ece63b64e.
This should be okay because #90329 has been merged.
r? `@joshtriplett`
The src pointers in CopyOnDrop and InsertionHole used to be *mut T, and
were derived via automatic conversion from &mut T. According to Stacked
Borrows 2.1, this means that those pointers become invalidated by
interior mutation in the comparison function.
But there's no need for mutability in this code path. Thus, we can
change the drop guards to use *const and derive those from &T.
Add a space and 2 grave accents
I only noticed this because I have this implementation copy pasted in some places in my code and I really can't wait for this to be stabilized...
Mark defaulted `PartialEq`/`PartialOrd` methods as const
WIthout it, `const` impls of these traits are unpleasant to write. I think this kind of change is allowed now. although it looks like it might require some Miri tweaks. Let's find out.
r? ```@fee1-dead```
Do array-slice equality via array equality, rather than always via slices
~~Draft because it needs a rebase after #91766 eventually gets through bors.~~
This enables the optimizations from #85828 to be used for array-to-slice comparisons too, not just array-to-array.
For example, <https://play.rust-lang.org/?version=nightly&mode=release&edition=2021&gist=5f9ba69b3d5825a782f897c830d3a6aa>
```rust
pub fn demo(x: &[u8], y: [u8; 4]) -> bool {
*x == y
}
```
Currently writes the array to stack for no reason:
```nasm
sub rsp, 4
mov dword ptr [rsp], edx
cmp rsi, 4
jne .LBB0_1
mov eax, dword ptr [rdi]
cmp eax, dword ptr [rsp]
sete al
add rsp, 4
ret
.LBB0_1:
xor eax, eax
add rsp, 4
ret
```
Whereas with the change in this PR it just compares it directly:
```nasm
cmp rsi, 4
jne .LBB1_1
cmp dword ptr [rdi], edx
sete al
ret
.LBB1_1:
xor eax, eax
ret
```