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)>`.
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.
Revert "Rollup merge of #97346 - JohnTitor:remove-back-compat-hacks, …
…r=oli-obk"
This reverts commit c703d11dccb4a895c7aead3b2fcd8cea8c483184, reversing
changes made to 64eb9ab869bc3f9ef3645302fbf22e706eea16cf.
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.
Rollup of 9 pull requests
Successful merges:
- #97962 (Make must_not_suspend lint see through references when drop tracking is enabled)
- #99966 (avoid assertion failures in try_to_scalar_int)
- #100637 (Improving Fuchsia rustc support documentation)
- #100643 (Point at a type parameter shadowing another type)
- #100651 (Migrations for rustc_expand transcribe.rs)
- #100669 (Attribute cleanups)
- #100670 (Fix documentation of rustc_parse::parser::Parser::parse_stmt_without_recovery)
- #100674 (Migrate lint reports in typeck::check_unused to LintDiagnostic)
- #100688 (`ty::Error` does not match other types for region constraints)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Migrate lint reports in typeck::check_unused to LintDiagnostic
In this PR, I migrate two lint reports in `typeck::check_unused` by `LintDiagnostic`, all of which is about extern crates.
```@rustbot``` label +A-translation
r? rust-lang/diagnostics
Fix documentation of rustc_parse::parser::Parser::parse_stmt_without_recovery
Something seems to have gotten out of sync during the creation of #81177, where both the argument and comment were introduced.
Migrations for rustc_expand transcribe.rs
This PR includes some migrations to the new diagnostics API for the `rustc_expand` module.
r? ```@davidtwco```
Improving Fuchsia rustc support documentation
* Adjusting `package/meta/package` to fit current schema
* Adding repository server step
* Adjusting step to give default repository
* Adding "recreate" step for easier step following
avoid assertion failures in try_to_scalar_int
Given that this is called `try_to_scalar_int`, we probably shouldn't `assert_int` here. Similarly `try_to_bits` also doesn't `assert!` that the size is correct.
Also add some `track_caller` for debugging, while we are at it.
r? ```@oli-obk```
Make must_not_suspend lint see through references when drop tracking is enabled
See #97333.
With drop tracking enabled, sometimes values that were previously linted are now considered dropped and not linted. This change makes must_not_suspend traverse through references to still catch these values.
Unfortunately, this leads to duplicate warnings in some cases (e.g. [dedup.rs](9a74608543/src/test/ui/lint/must_not_suspend/dedup.rs (L4))), so we only use the new behavior when drop tracking is enabled.
cc ``@guswynn``
Support 128-bit atomics on all aarch64 targets
Some aarch64 targets currently set `max_atomic_width` to 64, but aarch64 always supports 128-bit atomics.
r? `@Amanieu`
Remove manual implementations of HashStable for hir::Expr and hir::Ty.
We do not need to force hashing HIR bodies inside those nodes. The contents of bodies are not accessible from the `hir_owner` query which used `hash_without_bodies`. When the content of a body is required, the access is still done using `hir_owner_nodes`, which continues hashing HIR bodies.
Do not unconditionally succeed RUSTC_WRAPPER checks when run by build scripts
rust-analyzer's RUSTC_WRAPPER unconditionally succeeds `cargo check`
invocations tripping up build scripts using `cargo check` to probe for
successful compilations. To prevent this from happening the RUSTC_WRAPPER
now checks if it's run from a build script by looking for the
`CARGO_CFG_TARGET_ARCH` env var that cargo sets only when running build
scripts.
rust-analyzer's RUSTC_WRAPPER unconditionally succeeds `cargo check`
invocations tripping up build scripts using `cargo check` to probe for
successful compilations. To prevent this from happening the RUSTC_WRAPPER
now checks if it's run from a build script by looking for the
`CARGO_CFG_TARGET_ARCH` env var that cargo sets only when running build
scripts.
Make `Name` hold escaped name
Resolves#12787Resolvesrust-lang/rust#99361
This PR effectively swaps `Name` and `EscapedName` in hir. In other words, it makes `Name` hold and print escaped raw identifiers and introduces another struct `UnescapedName` for cases where you need to print names without "r#" prefix.
My rationale is that it makes it easier for us to format an escaped name into string, which is what we want when we serialize names in general. This is because we format a name into string usually when we are presenting it to the users and arguably they expect its escaped form as that's what they see and write in the source code.
I split the change for `Name` into 3 commits to make it easier to follow but it also made some tests fail in the intermediate commits. I can squash them into a commit after the review if desired. I've also made similar changes for `ModPath` and `EscapedModPath` as it makes them consistent with `Name`.
For reference, there was a brief discussion on this in [a zulip thread](https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/escaping.20.60Name.60s).
Update to LLVM 15
For preliminary testing. Some LLVM 15 compatibility fixes were applied separately in #99512.
Release timeline:
* LLVM 15 branched on Jul 26.
* The final LLVM 15.0.0 release is scheduled for Sep 6.
* Current nightly (1.65.0) is scheduled for Nov 3.
Changes in this PR (apart from the LLVM update):
* Pass `--set llvm.allow-old-toolchain` for many Docker images. LLVM 16 will require GCC >= 7.1, while LLVM 15 still allows older compilers with an option. Specify the option for builders still using GCC 5.4. #95026 updated some of the used toolchains, but not all.
* Use the `+atomics-32` target feature for thumbv6m.
* Explicitly link libatomic when cross-compiling LLVM to 32-bit target.
* Explicitly disable zstd support, to avoid libzstd.so dependency.
New LLVM patches ([commits](https://github.com/rust-lang/llvm-project/commits/rustc/15.0-2022-08-09)):
* [rust-only] Fix ICE with GCC 5.4 (15be58d7f0)
* [rust-only] Fix build with GCC 5.4 (774edc10fa)
* ~~[rust-only] Fix build with GCC 5.2 (1a6069a7bb)~~
* ~~[rust-only] Fix ICE with GCC 5.2 (493081f290)~~
* ~~[rust-only] Fix build with GCC 5.2 (0fc5979d73)~~
* [backported] Addition of `+atomics` target feature (57bdd9892d).
* [backported] Revert compiler-rt change that broke powerpc (9c68b43915)
* [awaiting backport] Fix RelLookupTableConverter on gnux32 (639388a05f / https://github.com/llvm/llvm-project/issues/57021)
Tested images: dist-x86_64-linux, armhf-gnu, arm-android, dist-s390x-linux, dist-x86_64-illumos, dist-x86_64-freebsd, wasm32, dist-x86_64-musl, dist-various-1, dist-riscv64-linux, dist-mips-linux, dist-mipsel-linux, dist-powerpc-linux, dist-aarch64-linux, dist-x86_64-apple, x86_64-msvc-1, x86_64-msvc-2, dist-various-2, dist-arm-linux
Tested up to the usual ipv6 error: test-various, i686-gnu, x86_64-gnu-nopt
r? `@ghost`
Keep going if normalized projection has unevaluated consts in `QueryNormalizer`
#100312 was the wrong approach, I think this is the right one.
When normalizing a type, if we see that it's a projection, we currently defer to `tcx.normalize_projection_ty`, which normalizes the projections away but doesn't touch the unevaluated constants. So now we just continue to fold the type if it has unevaluated constants so we make sure to evaluate those too, if we can.
Fixes#100217Fixes#83972Fixes#84669Fixes#86710Fixes#82268Fixes#73298
Replace pointer casting in hashmap_random_keys with safe code
The old code was unnecessarily unsafe and relied on the layout of tuples always being the same as an array of the same size (which might be bad with `-Z randomize-layout`)?
The replacement has [identical codegen](https://rust.godbolt.org/z/qxsvdb8nx), so it seems like a reasonable change.