Translate counters from Rust 1-based to LLVM 0-based counter ids
A colleague contacted me and asked why Rust's counters start at 1, when
Clangs appear to start at 0. There is a reason why Rust's internal
counters start at 1 (see the docs), and I tried to keep them consistent
when codegenned to LLVM's coverage mapping format. LLVM should be
tolerant of missing counters, but as my colleague pointed out,
`llvm-cov` will silently fail to generate a coverage report for a
function based on LLVM's assumption that the counters are 0-based.
See:
https://github.com/llvm/llvm-project/blob/main/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp#L170
Apparently, if, for example, a function has no branches, it would have
exactly 1 counter. `CounterValues.size()` would be 1, and (with the
1-based index), the counter ID would be 1. This would fail the check
and abort reporting coverage for the function.
It turns out that by correcting for this during coverage map generation,
by subtracting 1 from the Rust Counter ID (both when generating the
counter increment intrinsic call, and when adding counters to the map),
some uncovered functions (including in tests) now appear covered! This
corrects the coverage for a few tests!
r? `@tmandry`
FYI: `@wesleywiser`
Avoid sorting by DefId for `necessary_variants()`
Follow-up to https://github.com/rust-lang/rust/pull/83074. Originally I tried removing `impl Ord for DefId` but that hit *lots* of errors 😅 so I thought I would start with easy things.
I am not sure whether this could actually cause invalid query results, but this is used from `MarkSymbolVisitor::visit_arm` so it's at least feasible.
r? `@Aaron1011`
A colleague contacted me and asked why Rust's counters start at 1, when
Clangs appear to start at 0. There is a reason why Rust's internal
counters start at 1 (see the docs), and I tried to keep them consistent
when codegenned to LLVM's coverage mapping format. LLVM should be
tolerant of missing counters, but as my colleague pointed out,
`llvm-cov` will silently fail to generate a coverage report for a
function based on LLVM's assumption that the counters are 0-based.
See:
https://github.com/llvm/llvm-project/blob/main/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp#L170
Apparently, if, for example, a function has no branches, it would have
exactly 1 counter. `CounterValues.size()` would be 1, and (with the
1-based index), the counter ID would be 1. This would fail the check
and abort reporting coverage for the function.
It turns out that by correcting for this during coverage map generation,
by subtracting 1 from the Rust Counter ID (both when generating the
counter increment intrinsic call, and when adding counters to the map),
some uncovered functions (including in tests) now appear covered! This
corrects the coverage for a few tests!
Maintain supported sanitizers as a target property
In an effort to remove a hard-coded allow-list for target-sanitizer support correspondence, this PR moves the configuration to the target options.
Perhaps the one notable change made in this PR is this doc-comment:
```rust
/// The sanitizers supported by this target
///
/// Note that the support here is at a codegen level. If the machine code with sanitizer
/// enabled can generated on this target, but the necessary supporting libraries are not
/// distributed with the target, the sanitizer should still appear in this list for the target.
```
Previously the target would typically be added to the allow-list at the same time as the supporting runtime libraries are shipped for the target. However whether we ship the runtime libraries or not needn't be baked into the compiler; and if we don't users will receive a significantly more directed error about library not being found.
Fixes#81802
This commit adds an additional target property – `supported_sanitizers`,
and replaces the hardcoded allowlists in argument parsing to use this
new property.
Fixes#81802
This should have no real effect in most cases, as e.g. `hidden`
visibility already implies `dso_local` (or at least LLVM IR does not
preserve the `dso_local` setting if the item is already `hidden`), but
it should fix `-Crelocation-model=static` and improve codegen in
executables.
Note that this PR does not exhaustively port the logic in [clang]. Only
the obviously correct portion and what is necessary to fix a regression
from LLVM 12 that relates to `-Crelocation_model=static`.
Fixes#83335
[clang]: 3001d080c8/clang/lib/CodeGen/CodeGenModule.cpp (L945-L1039)
2229: Support migration via rustfix
- Adds support of machine applicable suggestions for `disjoint_capture_drop_reorder`.
- Doesn't migrate in the case of pre-existing bugs in user code
r? ``@nikomatsakis``
Only public items are monomorphization roots. This can be confirmed by noting that this program compiles:
```rust
fn foo<T>() { if true { foo::<Option<T>>() } }
fn bar() { foo::<()>() }
```
Rollup of 5 pull requests
Successful merges:
- #83535 (Break when there is a mismatch in the type count)
- #83721 (Add a button to copy the "use statement")
- #83740 (Fix comment typo in once.rs)
- #83745 (Add my new email address to .mailmap)
- #83754 (Add test to ensure search tabs behaviour)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
Break when there is a mismatch in the type count
When other errors are generated, there can be a mismatch between the
amount of input types in MIR, and the amount in the function itself.
Break from the comparative loop if this is the case to prevent
out-of-bounds.
Fixes#83499
normalize mir::Constant differently from ty::Const in preparation for valtrees
Valtrees are unable to represent many kind of constant values (this is on purpose). For constants that are used at runtime, we do not need a valtree representation and can thus use a different form of evaluation. In order to make this explicit and less fragile, I added a `fold_constant` method to `TypeFolder` and implemented it for normalization. Normalization can now, when it wants to eagerly evaluate a constant, normalize `mir::Constant` directly into a `mir::ConstantKind::Val` instead of relying on the `ty::Const` evaluation.
In the future we can get rid of the `ty::Const` in there entirely and add our own `Unevaluated` variant to `mir::ConstantKind`. This would allow us to remove the `promoted` field from `ty::ConstKind::Unevaluated`, as promoteds can never occur in the type system.
cc `@rust-lang/wg-const-eval`
r? `@lcnr`
Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
Fixes#80936.
"spotlight" is not a very specific or self-explaining name.
Additionally, the dialog that it triggers is called "Notable traits".
So, "notable trait" is a better name.
* Rename `#[doc(spotlight)]` to `#[doc(notable_trait)]`
* Rename `#![feature(doc_spotlight)]` to `#![feature(doc_notable_trait)]`
* Update documentation
* Improve documentation
r? `@Manishearth`
Fix expected/found order on impl trait projection mismatch error
fixes#68561
This PR adds a new `ObligationCauseCode` used when checking the concrete type of an impl trait satisfies its bounds, and checks for that cause code in the existing test to see if a projection's normalized type should be the "expected" or "found" type.
The second commit adds a `peel_derives` to that test, which appears to be necessary in some cases (see projection-mismatch-in-impl-where-clause.rs, which would still give expected/found in the wrong order otherwise). This caused some other changes in diagnostics not involving impl trait, but they look correct to me.
Stream the dep-graph to a file instead of storing it in-memory.
This is a reimplementation of #60035.
Instead of storing the dep-graph in-memory, the nodes are encoded as they come
into the a temporary file as they come. At the end of a successful the compilation,
this file is renamed to be the persistent dep-graph, to be decoded during the next
compilation session.
This two-files scheme avoids overwriting the dep-graph on unsuccessful or crashing compilations.
The structure of the file is modified to be the sequence of `(DepNode, Fingerprint, EdgesVec)`.
The deserialization is responsible for going to the more compressed representation.
The `node_count` and `edge_count` are stored in the last 16 bytes of the file,
in order to accurately reserve capacity for the vectors.
At the end of the compilation, the encoder is flushed and dropped.
The graph is not usable after this point: any creation of a node will ICE.
I had to retrofit the debugging options, which is not really pretty.
rustdoc: Only look at blanket impls in `get_blanket_impls`
The idea here is that all the work in 16156fb278/compiler/rustc_middle/src/ty/trait_def.rs (L172-L186) doesn't matter for `get_blanket_impls` - Rustdoc will already pick up on those blocks when it documents the item.
Run LLVM coverage instrumentation passes before optimization passes
This matches the behavior of Clang and allows us to remove several
hacks which were needed to ensure functions weren't optimized away
before reaching the instrumentation pass.
Fixes#83429
cc `@richkadel`
r? `@tmandry`
Don't duplicate the extern providers once for each crate
This should give a small perf improvement for small crates by avoiding a memcpy of a pretty big struct for each loaded crate. In addition would be useful for replacing the sequential `CrateNum` everywhere with the hash based `StableCrateId` introduced in #81635, which would allow avoiding remapping of `CrateNum`'s when loading crate metadata. While this PR is not strictly needed for that, it is necessary to prevent a performance loss due to it.
I think this duplication was done in https://github.com/rust-lang/rust/pull/40008 (which introduced the query system) to make it possible to compile multiple crates in a single session in the future. I think this is unlikely to be implemented any time soon. In addition this PR can easily be reverted if necessary to implement this.
When the problem for a method not being found in its receiver is due to
arbitrary self-types, we don't want to mention importing or implementing
the trait, instead we suggest wrapping.
This matches the behavior of Clang and allows us to remove several
hacks which were needed to ensure functions weren't optimized away
before reaching the instrumentation pass.
There isn't currently a good reviewer for these, and I don't want to
remove things that will just be added again. I plan to make a separate
PR for these changes so the rest of the cleanup can land.