Depend on rustc_abi in compiler crates that use it indirectly but have
not yet taken on that dependency, and are not entangled in my other PRs.
This leaves an "excise rustc_target" step after the dust settles.
coverage: Don't rely on the custom traversal to find enclosing loops
This opens up the possibility of modifying or removing the custom graph traversal used in coverage counter creation, without losing access to the heuristics that care about a node's enclosing loops.
Actually changing the traversal is left for future work, because this PR on its own doesn't change the emitted coverage mappings at all.
Rollup of 4 pull requests
Successful merges:
- #132123 (allow type-based search on foreign functions)
- #132183 (Fix code HTML items making big blocks if too long)
- #132192 (expand: Stop using artificial `ast::Item` for macros loaded from metadata)
- #132205 (docs: Correctly link riscv32e from platform-support.md)
r? `@ghost`
`@rustbot` modify labels: rollup
expand: Stop using artificial `ast::Item` for macros loaded from metadata
You don't need a full `Item` for that, and not using a piece of AST helps with https://github.com/rust-lang/rust/pull/131808.
Replace some LLVMRust wrappers with calls to the LLVM C API
This PR removes the LLVMRust wrapper functions for getting/setting linkage and visibility, and replaces them with direct calls to the corresponding functions in LLVM's C API.
To make this convenient and sound, two pieces of supporting code have also been added:
- A simple proc-macro that derives `TryFrom<u32>` for fieldless enums
- A wrapper type for C enum values returned by LLVM functions, to ensure soundness if LLVM returns an enum value we don't know about
In a few places, the use of safe wrapper functions means that an `unsafe` block is no longer needed, so the affected code has changed its indentation level.
rustc_target: Add pauth-lr aarch64 target feature
Add the pauth-lr target feature, corresponding to aarch64 FEAT_PAuth_LR. This feature has been added in LLVM 19.
It is currently not supported by the Linux hwcap and so we cannot add runtime feature detection for it at this time.
r? `@Amanieu`
Downgrade `untranslatable_diagnostic` and `diagnostic_outside_of_impl` to `allow`
Current implementation of translatable diagnostics infrastructure unfortunately causes some friction for compiler contributors. While we don't have a redesign that causes less friction in place, let's downgrade the internal `untranslatable_diagnostic` and `diagnostic_outside_of_impl` lints so we don't indicate to contributors that they *have* to use the current translation infra.
I purposefully left `#[allow(untranslatable_diagnostic)]` and `#[allow(diagnostic_outside_of_impl)]` instances untouched because that seems like unnecessary additional churn.
See <https://github.com/rust-lang/rust/issues/132181> for context.
r? `@davidtwco` (or wg-diagnostics/compiler)
(Big performance change) Do not run lints that cannot emit
Before this change, adding a lint was a difficult matter because it always had some overhead involved. This was because all lints would run, no matter their default level, or if the user had `#![allow]`ed them. This PR changes that. This change would improve both the Rust lint infrastructure and Clippy, but Clippy will see the most benefit, as it has about 900 registered lints (and growing!)
So yeah, with this little patch we filter all lints pre-linting, and remove any lint that is either:
- Manually `#![allow]`ed in the whole crate,
- Allowed in the command line, or
- Not manually enabled with `#[warn]` or similar, and its default level is `Allow`
As some lints **need** to run, this PR also adds **loadbearing lints**. On a lint declaration, you can use the ``@eval_always` = true` marker to label it as loadbearing. A loadbearing lint will never be filtered (it will always run)
Fixes#106983
Deny calls to non-`#[const_trait]` methods in MIR constck
This is a (potentially temporary) fix that closes off the mismatch in assumptions between MIR constck and typeck which does the const traits checking. Before this PR, MIR constck assumed that typeck correctly handled all calls to trait methods in const contexts if effects is enabled. That is not true because typeck only correctly handles callees that are const. For non-const callees (such as methods in a non-const_trait), typeck had never created an error.
45089ec19e/compiler/rustc_hir_typeck/src/callee.rs (L876-L877)
I called this potentially temporary because the const checks could be moved to HIR entirely. Alongside the recent refactor in const stability checks where that component could be placed would need more discussion. (cc ```@compiler-errors``` ```@RalfJung)```
Tests are updated, mainly due to traits not being const in core, so tests that call them correctly error.
This fixes https://github.com/rust-lang/project-const-traits/issues/12.
coverage: Consolidate creation of covmap/covfun records
This code for creating covmap/covfun records during codegen was split across multiple functions and files for dubious historical reasons. Having it all in one place makes it easier to follow.
This PR also includes two semi-related cleanups:
- Getting the codegen context's `coverage_cx` state is made infallible, since it should always exist when running the code paths that need it.
- The value of `covfun_section_name` is saved in the codegen context, since it never changes at runtime, and the code that needs it has access to the context anyway.
---
Background: Coverage instrumentation generates two kinds of metadata that are embedded in the final binary. There is per-CGU information that goes in the `__llvm_covmap` linker section, and per-function information that goes in the `__llvm_covfun` section (except on Windows, where slightly different section names are used).
Effects cleanup
- removed extra bits from predicates queries that are no longer needed in the new system
- removed the need for `non_erasable_generics` to take in tcx and DefId, removed unused arguments in callers
r? compiler-errors
Use `Enabled{Lang,Lib}Feature` instead of n-tuples
Instead of passing around e.g. `(gate_name, attr_span, stable_since)` 3-tuples for enabled lang features or `(gate_name, attr_span)` 2-tuples for enabled lib features, use `Enabled{Lang,Lib}Feature` structs with named fields.
Also did some minor code-golfing of involved iterator chains to hopefully make them easier to follow.
Follow-up to https://github.com/rust-lang/rust/pull/132098#issuecomment-2434523431 cc `@RalfJung.`
- removed extra bits from predicates queries that are no longer needed in the new system
- removed the need for `non_erasable_generics` to take in tcx and DefId, removed unused arguments in callers
Const stability checks v2
The const stability system has served us well ever since `const fn` were first stabilized. It's main feature is that it enforces *recursive* validity -- a stable const fn cannot internally make use of unstable const features without an explicit marker in the form of `#[rustc_allow_const_fn_unstable]`. This is done to make sure that we don't accidentally expose unstable const features on stable in a way that would be hard to take back. As part of this, it is enforced that a `#[rustc_const_stable]` can only call `#[rustc_const_stable]` functions. However, some problems have been coming up with increased usage:
- It is baffling that we have to mark private or even unstable functions as `#[rustc_const_stable]` when they are used as helpers in regular stable `const fn`, and often people will rather add `#[rustc_allow_const_fn_unstable]` instead which was not our intention.
- The system has several gaping holes: a private `const fn` without stability attributes whose inherited stability (walking up parent modules) is `#[stable]` is allowed to call *arbitrary* unstable const operations, but can itself be called from stable `const fn`. Similarly, `#[allow_internal_unstable]` on a macro completely bypasses the recursive nature of the check.
Fundamentally, the problem is that we have *three* disjoint categories of functions, and not enough attributes to distinguish them:
1. const-stable functions
2. private/unstable functions that are meant to be callable from const-stable functions
3. functions that can make use of unstable const features
Functions in the first two categories cannot use unstable const features and they can only call functions from the first two categories.
This PR implements the following system:
- `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions.
- `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category.
- `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls.
Also, all the holes mentioned above have been closed. There's still one potential hole that is hard to avoid, which is when MIR building automatically inserts calls to a particular function in stable functions -- which happens in the panic machinery. Those need to be manually marked `#[rustc_const_stable_indirect]` to be sure they follow recursive const stability. But that's a fairly rare and special case so IMO it's fine.
The net effect of this is that a `#[unstable]` or unmarked function can be constified simply by marking it as `const fn`, and it will then be const-callable from stable `const fn` and subject to recursive const stability requirements. If it is publicly reachable (which implies it cannot be unmarked), it will be const-unstable under the same feature gate. Only if the function ever becomes `#[stable]` does it need a `#[rustc_const_unstable]` or `#[rustc_const_stable]` marker to decide if this should also imply const-stability.
Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to use unstable const lang features (including intrinsics), or (b) `#[stable]` functions that are not yet intended to be const-stable. Adding `#[rustc_const_stable]` is only needed for functions that are actually meant to be directly callable from stable const code. `#[rustc_const_stable_indirect]` is used to mark intrinsics as const-callable and for `#[rustc_const_unstable]` functions that are actually called from other, exposed-on-stable `const fn`. No other attributes are required.
Also see the updated dev-guide at https://github.com/rust-lang/rustc-dev-guide/pull/2098.
I think in the future we may want to tweak this further, so that in the hopefully common case where a public function's const-stability just exactly mirrors its regular stability, we never have to add any attribute. But right now, once the function is stable this requires `#[rustc_const_stable]`.
### Open question
There is one point I could see we might want to do differently, and that is putting `#[rustc_const_unstable]` functions (but not intrinsics) in category 2 by default, and requiring an extra attribute for `#[rustc_const_not_exposed_on_stable]` or so. This would require a bunch of extra annotations, but would have the advantage that turning a `#[rustc_const_unstable]` into `#[rustc_const_stable]` will never change the way the function is const-checked. Currently, we often discover in the const stabilization PR that a function needs some other unstable const things, and then we rush to quickly deal with that. In this alternative universe, we'd work towards getting rid of the `rustc_const_not_exposed_on_stable` before stabilization, and once that is done stabilization becomes a trivial matter. `#[rustc_const_stable_indirect]` would then only be used for intrinsics.
I think I like this idea, but might want to do it in a follow-up PR, as it will need a whole bunch of annotations in the standard library. Also, we probably want to convert all const intrinsics to the "new" form (`#[rustc_intrinsic]` instead of an `extern` block) before doing this to avoid having to deal with two different ways of declaring intrinsics.
Cc `@rust-lang/wg-const-eval` `@rust-lang/libs-api`
Part of https://github.com/rust-lang/rust/issues/129815 (but not finished since this is not yet sufficient to safely let us expose `const fn` from hashbrown)
Fixes https://github.com/rust-lang/rust/issues/131073 by making it so that const-stable functions are always stable
try-job: test-various
Then we can rename the _raw functions to drop their suffix, and instead
explicitly use is_stable_const_fn for the few cases where that is really what
you want.
Pass Ident by reference in ast Visitor
`MutVisitor`'s version of `visit_ident` passes around `&Ident`, but `Visitor` copies `Ident`. This PR changes that
r? `@petrochenkov`
related to #128974
Fundamentally, we have *three* disjoint categories of functions:
1. const-stable functions
2. private/unstable functions that are meant to be callable from const-stable functions
3. functions that can make use of unstable const features
This PR implements the following system:
- `#[rustc_const_stable]` puts functions in the first category. It may only be applied to `#[stable]` functions.
- `#[rustc_const_unstable]` by default puts functions in the third category. The new attribute `#[rustc_const_stable_indirect]` can be added to such a function to move it into the second category.
- `const fn` without a const stability marker are in the second category if they are still unstable. They automatically inherit the feature gate for regular calls, it can now also be used for const-calls.
Also, several holes in recursive const stability checking are being closed.
There's still one potential hole that is hard to avoid, which is when MIR
building automatically inserts calls to a particular function in stable
functions -- which happens in the panic machinery. Those need to *not* be
`rustc_const_unstable` (or manually get a `rustc_const_stable_indirect`) to be
sure they follow recursive const stability. But that's a fairly rare and special
case so IMO it's fine.
The net effect of this is that a `#[unstable]` or unmarked function can be
constified simply by marking it as `const fn`, and it will then be
const-callable from stable `const fn` and subject to recursive const stability
requirements. If it is publicly reachable (which implies it cannot be unmarked),
it will be const-unstable under the same feature gate. Only if the function ever
becomes `#[stable]` does it need a `#[rustc_const_unstable]` or
`#[rustc_const_stable]` marker to decide if this should also imply
const-stability.
Adding `#[rustc_const_unstable]` is only needed for (a) functions that need to
use unstable const lang features (including intrinsics), or (b) `#[stable]`
functions that are not yet intended to be const-stable. Adding
`#[rustc_const_stable]` is only needed for functions that are actually meant to
be directly callable from stable const code. `#[rustc_const_stable_indirect]` is
used to mark intrinsics as const-callable and for `#[rustc_const_unstable]`
functions that are actually called from other, exposed-on-stable `const fn`. No
other attributes are required.
Emit future-incompatibility lint when calling/declaring functions with vectors that require missing target feature
On some architectures, vector types may have a different ABI depending on whether the relevant target features are enabled. (The ABI when the feature is disabled is often not specified, but LLVM implements some de-facto ABI.)
As discussed in https://github.com/rust-lang/lang-team/issues/235, this turns out to very easily lead to unsound code.
This commit makes it a post-monomorphization error to declare or call functions using those vector types in a context in which the corresponding target features are disabled, if using an ABI for which the difference is relevant. This ensures that these functions are always called with a consistent ABI.
See the [nomination comment](https://github.com/rust-lang/rust/pull/127731#issuecomment-2288558187) for more discussion.
r? RalfJung
Part of https://github.com/rust-lang/rust/issues/116558
On some architectures, vector types may have a different ABI when
relevant target features are enabled.
As discussed in https://github.com/rust-lang/lang-team/issues/235, this
turns out to very easily lead to unsound code.
This commit makes it an error to declare or call functions using those
vector types in a context in which the corresponding target features are
disabled, if using an ABI for which the difference is relevant.
coverage: Emit LLVM intrinsics using the normal helper method
Codegen already has convenient ways to declare and emit LLVM intrinsics, so there's no need for coverage instrumentation to jump through hoops to emit them manually.
Add support for `~const` item bounds
Supports the only missing capability of `~const` associated types that I can think of now (this is obviously excluding `~const` opaques, which I see as an extension to this; I'll probably do that next).
r? ``@lcnr`` mostly b/c it changes candidate assembly, or reassign
cc ``@fee1-dead``
Adding an extra `OnceCell` to `CrateCoverageContext` is much nicer than trying
to thread this string through multiple layers of function calls that already
have access to the context.