Rollup of 9 pull requests
Successful merges:
- #99576 (Do not allow `Drop` impl on foreign fundamental types)
- #100081 (never consider unsafe blocks unused if they would be required with deny(unsafe_op_in_unsafe_fn))
- #100208 (make NOP dyn casts not require anything about the vtable)
- #100494 (Cleanup rustdoc themes)
- #100522 (Only check the `DefId` for the recursion check in MIR inliner.)
- #100592 (Manually implement Debug for ImportKind.)
- #100598 (Don't fix builtin index when Where clause is found)
- #100721 (Add diagnostics lints to `rustc_type_ir` module)
- #100731 (rustdoc: count deref and non-deref as same set of used methods)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Lazily decode SourceFile from metadata
Currently, source files from foreign crates are decoded up-front from metadata.
Spans from those crates were matched with the corresponding source using binary search among those files.
This PR changes the strategy by matching spans to files during encoding. This allows to decode source files on-demand, instead of up-front. The on-disk format for spans becomes: `<tag> <position from start of file> <length> <file index> <crate (if foreign file)>`.
This verifies if the HEAD sha matches with the detected LLVM SHA, and if not,
permits usage of the detected LLVM. Otherwise, we fallback on regular
non-downloaded LLVM (currently still cached with sccache, though that's still
10+ minutes on macOS).
Don't fix builtin index when Where clause is found
Where clause shadows blanket impl for `Index` which causes normalization to not occur, which causes ICE to happen when we typeck.
r? `@compiler-errors`
Fixes#91633
Cleanup rustdoc themes
This PR continues our work to simplify the rustdoc themes by relying more on CSS variables. Interestingly enough, this time it allowed me to realize that we were having a lot of different colors for borders even though the difference is unnoticeable. I used this opportunity to unify them.
The live demo is [here](https://rustdoc.crud.net/imperio/cleanup-themes/std/index.html).
r? `@jsha`
never consider unsafe blocks unused if they would be required with deny(unsafe_op_in_unsafe_fn)
Judging from https://github.com/rust-lang/rust/issues/71668#issuecomment-1200317370 the consensus nowadays seems to be that we should never consider an unsafe block unused if it was required with `deny(unsafe_op_in_unsafe_fn)`, no matter whether that lint is actually enabled or not. So let's adjust rustc accordingly.
The first commit does the change, the 2nd does some cleanup.
Do not allow `Drop` impl on foreign fundamental types
`Drop` should not be implemented on `Pin<T>` even if `T` is local.
This does not trigger regular orphan rules is because `Pin` is `#[fundamental]`... but we don't allow specialized `Drop` impls anyways, so these rules are not sufficient to prevent this impl on stable. Let's just choose even stricter rules, since we shouldn't be implementing `Drop` on a foreign ADT ever.
Fixes#99575
Refactor iteration logic in the `Flatten` and `FlatMap` iterators
The `Flatten` and `FlatMap` iterators both delegate to `FlattenCompat`:
```rust
struct FlattenCompat<I, U> {
iter: Fuse<I>,
frontiter: Option<U>,
backiter: Option<U>,
}
```
Every individual iterator method that `FlattenCompat` implements needs to carefully manage this state, checking whether the `frontiter` and `backiter` are present, and storing the current iterator appropriately if iteration is aborted. This has led to methods such as `next`, `advance_by`, and `try_fold` all having similar code for managing the iterator's state.
I have extracted this common logic of iterating the inner iterators with the option to exit early into a `iter_try_fold` method:
```rust
impl<I, U> FlattenCompat<I, U>
where
I: Iterator<Item: IntoIterator<IntoIter = U>>,
{
fn iter_try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
where
Fold: FnMut(Acc, &mut U) -> R,
R: Try<Output = Acc>,
{ ... }
}
```
It passes each of the inner iterators to the given function as long as it keep succeeding. It takes care of managing `FlattenCompat`'s state, so that the actual `Iterator` methods don't need to. The resulting code that makes use of this abstraction is much more straightforward:
```rust
fn next(&mut self) -> Option<U::Item> {
#[inline]
fn next<U: Iterator>((): (), iter: &mut U) -> ControlFlow<U::Item> {
match iter.next() {
None => ControlFlow::CONTINUE,
Some(x) => ControlFlow::Break(x),
}
}
self.iter_try_fold((), next).break_value()
}
```
Note that despite being implemented in terms of `iter_try_fold`, `next` is still able to benefit from `U`'s `next` method. It therefore does not take the performance hit that implementing `next` directly in terms of `Self::try_fold` causes (in some benchmarks).
This PR also adds `iter_try_rfold` which captures the shared logic of `try_rfold` and `advance_back_by`, as well as `iter_fold` and `iter_rfold` for folding without early exits (used by `fold`, `rfold`, `count`, and `last`).
Benchmark results:
```
before after
bench_flat_map_sum 423,255 ns/iter 414,338 ns/iter
bench_flat_map_ref_sum 1,942,139 ns/iter 2,216,643 ns/iter
bench_flat_map_chain_sum 1,616,840 ns/iter 1,246,445 ns/iter
bench_flat_map_chain_ref_sum 4,348,110 ns/iter 3,574,775 ns/iter
bench_flat_map_chain_option_sum 780,037 ns/iter 780,679 ns/iter
bench_flat_map_chain_option_ref_sum 2,056,458 ns/iter 834,932 ns/iter
```
I added the last two benchmarks specifically to demonstrate an extreme case where `FlatMap::next` can benefit from custom internal iteration of the outer iterator, so take it with a grain of salt. We should probably do a perf run to see if the changes to `next` are worth it in practice.
rustc_metadata: dedupe strings to prevent multiple copies in rmeta/query cache blow file size
r? `@cjgillot`
Encodes strings in rmeta/query cache so duplicated ones will be encoded as offsets to first strings, reducing file size.
Reword "Required because of the requirements on the impl of ..."
Rephrases the awkward "Required because of the requirements on the impl of `{trait}` for `{type}`" to "required for `{type}` to implement `{trait}`"
Revert "Rollup merge of #97346 - JohnTitor:remove-back-compat-hacks, …
…r=oli-obk"
This reverts commit c703d11dcc, reversing
changes made to 64eb9ab869.
it didn't apply cleanly, so now it works the same for RPIT and for TAIT instead of just working for RPIT, but we should keep those in sync anyway. It also exposed a TAIT bug (see the feature gated test that now ICEs).
r? `@pnkfelix`
fixes#99536
Don't derive `PartialEq::ne`.
Currently we skip deriving `PartialEq::ne` for C-like (fieldless) enums
and empty structs, thus reyling on the default `ne`. This behaviour is
unnecessarily conservative, because the `PartialEq` docs say this:
> Implementations must ensure that eq and ne are consistent with each other:
>
> `a != b` if and only if `!(a == b)` (ensured by the default
> implementation).
This means that the default implementation (`!(a == b)`) is always good
enough. So this commit changes things such that `ne` is never derived.
The motivation for this change is that not deriving `ne` reduces compile
times and binary sizes.
Observable behaviour may change if a user has defined a type `A` with an
inconsistent `PartialEq` and then defines a type `B` that contains an
`A` and also derives `PartialEq`. Such code is already buggy and
preserving bug-for-bug compatibility isn't necessary.
Two side-effects of the change:
- There is only one error message produced for types where `PartialEq`
cannot be derived, instead of two.
- For coverage reports, some warnings about generated `ne` methods not
being executed have disappeared.
Both side-effects seem fine, and possibly preferable.