Don't make statement nonterminals match pattern nonterminals
Right now, the heuristic we use to check if a token may begin a pattern nonterminal falls back to `may_be_ident`:
ef71f1047e/compiler/rustc_parse/src/parser/nonterminal.rs (L21-L37)
This has the unfortunate side effect that a `stmt` nonterminal eagerly matches against a `pat` nonterminal, leading to a parse error:
```rust
macro_rules! m {
($pat:pat) => {};
($stmt:stmt) => {};
}
macro_rules! m2 {
($stmt:stmt) => {
m! { $stmt }
};
}
m2! { let x = 1 }
```
This PR fixes it by more accurately reflecting the set of nonterminals that may begin a pattern nonterminal.
As a side-effect, I modified `Token::can_begin_pattern` to work correctly and used that in `Parser::nonterminal_may_begin_with`.
We want to allow setting this on the CLI, override it only in MIR
passes, and disable it altogether in mir-opt tests.
The default value is "only for NLL MIR dumps", which is considered off
for all intents and purposes, except for `rustc_borrowck` when an NLL
MIR dump is requested.
Several compiler functions have `Option<!>` for their return type.
That's odd. The only valid return value is `None`, so why is this type
used?
Because it lets you write certain patterns slightly more concisely. E.g.
if you have these common patterns:
```
let Some(a) = f() else { return };
let Ok(b) = g() else { return };
```
you can shorten them to these:
```
let a = f()?;
let b = g().ok()?;
```
Huh.
An `Option` return type typically designates success/failure. How should
I interpret the type signature of a function that always returns (i.e.
doesn't panic), does useful work (modifying `&mut` arguments), and yet
only ever fails? This idiom subverts the type system for a cute
syntactic trick.
Furthermore, returning `Option<!>` from a function F makes things
syntactically more convenient within F, but makes things worse at F's
callsites. The callsites can themselves use `?` with F but should not,
because they will get an unconditional early return, which is almost
certainly not desirable. Instead the return value should be ignored.
(Note that some of callsites of `process_operand`, `process_immedate`,
`process_assign` actually do use `?`, though the early return doesn't
matter in these cases because nothing of significance comes after those
calls. Ugh.)
When I first saw this pattern I had no idea how to interpret it, and it
took me several minutes of close reading to understand everything I've
written above. I even started a Zulip thread about it to make sure I
understood it properly. "Save a few characters by introducing types so
weird that compiler devs have to discuss it on Zulip" feels like a bad
trade-off to me. This commit replaces all the `Option<!>` return values
and uses `else`/`return` (or something similar) to replace the relevant
`?` uses. The result is slightly more verbose but much easier to
understand.
This keeps it up-to-date by moving from 0.5.6 to 0.5.7. While here I've
additionally updated some other wasm-related dependencies in the
workspace to keep them up-to-date and try to avoid duplicate versions as
well.
Use a reduced recursion limit in the MIR inliner's cycle breaker
This probably papers over https://github.com/rust-lang/rust/issues/128887, but primarily I'm opening this PR because multiple compiler people have thought about making this change which probably means it's a good idea.
r? compiler-errors
debug-fmt-detail option
I'd like to propose a new option that makes `#[derive(Debug)]` generate no-op implementations that don't print anything, and makes `{:?}` in format strings a no-op.
There are a couple of motivations for this:
1. A more thorough stripping of debug symbols. Binaries stripped of debug symbols still retain some of them through `Debug` implementations. It's hard to avoid that without compiler's help, because debug formatting can be used in many places, including dependencies, and their loggers, asserts, panics, etc.
* In my testing it gives about 2% binary size reduction on top of all other binary-minimizing best practices (including `panic_immediate_abort`). There are targets like Web WASM or embedded where users pay attention to binary sizes.
* Users distributing closed-source binaries may not want to "leak" any symbol names as a matter of principle.
2. Adds ability to test whether code depends on specifics of the `Debug` format implementation in unwise ways (e.g. trying to get data unavailable via public interface, or using it as a serialization format). Because current Rust's debug implementation doesn't change, there's a risk of it becoming a fragile de-facto API that [won't be possible to change in the future](https://www.hyrumslaw.com/). An option that "breaks" it can act as a [grease](https://www.rfc-editor.org/rfc/rfc8701.html).
This implementation is a `-Z fmt-debug=opt` flag that takes:
* `full` — the default, current state.
* `none` — makes derived `Debug` and `{:?}` no-ops. Explicit `impl Debug for T` implementations are left unharmed, but `{:?}` format won't use them, so they may get dead-code eliminated if they aren't invoked directly.
* `shallow` — makes derived `Debug` print only the type's name, without recursing into fields. Fieldless enums print their variant names. `{:?}` works.
The `shallow` option is a compromise between minimizing the `Debug` code, and compatibility. There are popular proc-macro crates that use `Debug::fmt` as a way to convert enum values into their Rust source code.
There's a corresponding `cfg` flag: `#[cfg(fmt_debug = "none")]` that can be used in user code to react to this setting to minimize custom `Debug` implementations or remove unnecessary formatting helper functions.
By making it own the index maps, instead of holding references to them.
This requires moving the free function `find_candidate` into
`Candidate::reset_and_find`. It lets the `'alloc` lifetime be removed
everywhere that still has it.
Correct trusty targets to be tier 3
The Trusty targets were added in https://github.com/rust-lang/rust/pull/129490, but in that PR I accidentally marked them as tier 2. This PR corrects the target metadata to mark them as tier 3.
Move `'tcx` lifetime off of impl and onto methods for `CrateMetadataRef`
Unconstrained type and const variables are not allowed, but unconstrained lifetimes are. This is not very good style, though, and it leads to unnecessary captures of a lifetime in edition 2024 (not that it matters, but it does trigger the edition migration lint).
derive(SmartPointer): assume pointee from the single generic and better error messages
Fix#129465
Actually RFC says that `#[pointee]` can be inferred when there is no ambiguity, or there is only one generic type parameter so to say.
cc ```@Darksonn```
r? ```@compiler-errors```
Emit specific message for time<=0.3.35
```
error[E0282]: type annotations needed for `Box<_>`
--> /home/gh-estebank/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9
|
83 | let items = format_items
| ^^^^^
...
86 | Ok(items.into())
| ---- type must be known at this point
|
= note: this is an inference error on `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.36`
```
Partially mitigate the fallout from https://github.com/rust-lang/rust/issues/127343. Although the biggest benefit of this would have been if we had had this in 1.80 before it became stable, the long-tail of that change will be felt for a *long* time, so better late than never.
We can also emit an even more targeted error instead of this inference failure.
Add an ability to convert between `Span` and `visit::Location`
AFAIK, there is no way to create a `Location` from a `Span` because its only field is private. This makes it impossible to use visitor methods like `visit_statement` or `visit_terminator`.
This PR adds an implementation for`From<Span>` for `Location` to fix this.
r? ```@celinval```
rustc_target: Add various aarch64 features
Add various aarch64 features already supported by LLVM and Linux.
Additionally include some comment fixes to ensure consistency of feature names with the Arm ARM.
Compiler support for features added to stdarch by https://github.com/rust-lang/stdarch/pull/1614.
Tracking issue for unstable aarch64 features is https://github.com/rust-lang/rust/issues/127764.
List of added features:
- FEAT_CSSC
- FEAT_ECV
- FEAT_FAMINMAX
- FEAT_FLAGM2
- FEAT_FP8
- FEAT_FP8DOT2
- FEAT_FP8DOT4
- FEAT_FP8FMA
- FEAT_HBC
- FEAT_LSE128
- FEAT_LSE2
- FEAT_LUT
- FEAT_MOPS
- FEAT_LRCPC3
- FEAT_SVE_B16B16
- FEAT_SVE2p1
- FEAT_WFxT
- FEAT_SME
- FEAT_SME_F16F16
- FEAT_SME_F64F64
- FEAT_SME_F8F16
- FEAT_SME_F8F32
- FEAT_SME_FA64
- FEAT_SME_I16I64
- FEAT_SME_LUTv2
- FEAT_SME2
- FEAT_SME2p1
- FEAT_SSVE_FP8DOT2
- FEAT_SSVE_FP8DOT4
- FEAT_SSVE_FP8FMA
FEAT_FPMR is added in the first commit and then removed in a separate one to highlight it being removed from upstream LLVM 19. The intention is for it to be detectable at runtime through stdarch but not have a corresponding Rust compile-time feature.
Implement a first version of RFC 3525: struct target features
This PR is an attempt at implementing https://github.com/rust-lang/rfcs/pull/3525, behind a feature gate `struct_target_features`.
There's obviously a few tasks that ought to be done before this is merged; in no particular order:
- add proper error messages
- add tests
- create a tracking issue for the RFC
- properly serialize/deserialize the new target_features field in `rmeta` (assuming I even understood that correctly :-))
That said, as I am definitely not a `rustc` expert, I'd like to get some early feedback on the overall approach before fixing those things (and perhaps some pointers for `rmeta`...), hence this early PR :-)
Here's an example piece of code that I have been using for testing - with the new code, the calls to intrinsics get correctly inlined:
```rust
#![feature(struct_target_features)]
use std::arch::x86_64::*;
/*
// fails to compile
#[target_feature(enable = "avx")]
struct Invalid(u32);
*/
#[target_feature(enable = "avx")]
struct Avx {}
#[target_feature(enable = "sse")]
struct Sse();
/*
// fails to compile
extern "C" fn bad_fun(_: Avx) {}
*/
/*
// fails to compile
#[inline(always)]
fn inline_fun(_: Avx) {}
*/
trait Simd {
fn do_something(&self);
}
impl Simd for Avx {
fn do_something(&self) {
unsafe {
println!("{:?}", _mm256_setzero_ps());
}
}
}
impl Simd for Sse {
fn do_something(&self) {
unsafe {
println!("{:?}", _mm_setzero_ps());
}
}
}
struct WithAvx {
#[allow(dead_code)]
avx: Avx,
}
impl Simd for WithAvx {
fn do_something(&self) {
unsafe {
println!("{:?}", _mm256_setzero_ps());
}
}
}
#[inline(never)]
fn dosomething<S: Simd>(simd: &S) {
simd.do_something();
}
fn main() {
/*
// fails to compile
Avx {};
*/
if is_x86_feature_detected!("avx") {
let avx = unsafe { Avx {} };
dosomething(&avx);
dosomething(&WithAvx { avx });
}
if is_x86_feature_detected!("sse") {
dosomething(&unsafe { Sse {} })
}
}
```
Tracking:
- https://github.com/rust-lang/rust/issues/129107
```
error[E0282]: type annotations needed for `Box<_>`
--> ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/time-0.3.34/src/format_description/parse/mod.rs:83:9
|
83 | let items = format_items
| ^^^^^
...
86 | Ok(items.into())
| ---- type must be known at this point
|
= note: this is an inference error on crate `time` caused by a change in Rust 1.80.0; update `time` to version `>=0.3.35`
```
Partially address #127343.
coverage: Rename `CodeRegion` to `SourceRegion`
LLVM uses the word "code" to refer to a particular kind of coverage mapping. This unrelated usage of the word is confusing, and makes it harder to introduce types whose names correspond to the LLVM classification of coverage kinds.
No functional changes.
Rename `BikeshedIntrinsicFrom` to `TransmuteFrom`
As our implementation of MCP411 nears completion and we begin to solicit testing, it's no longer reasonable to expect testers to type or remember `BikeshedIntrinsicFrom`. The name degrades the ease-of-reading of documentation, and the overall experience of using compiler safe transmute.
Tentatively, we'll instead adopt `TransmuteFrom`.
This name seems to be the one most likely to be stabilized, after discussion on Zulip [1]. We may want to revisit the ordering of `Src` and `Dst` before stabilization, at which point we'd likely consider `TransmuteInto` or `Transmute`.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20should.20.60BikeshedIntrinsicFrom.60.20be.20named.3F
Tracking Issue: https://github.com/rust-lang/rust/issues/99571
r? `@compiler-errors`
interpret: do not make const-eval query result depend on tcx.sess
The check against calling functions with missing target features uses `tcx.sess` to determine which target features are available. However, this can differ between different crates in a crate graph, so the same const-eval query can come to different conclusions about whether a constant evaluates successfully or not -- which is bad, we should consistently get the same result everywhere.
const-eval: do not make UbChecks behavior depend on current crate's flags
Fixes https://github.com/rust-lang/rust/issues/129552
Let's see if we can get away with just always enabling these checks.
add repr to the allowlist for naked functions
Fixes#129412 (combining unstable features #90957 (`#![feature(naked_functions)]`) and #82232 (`#![feature(fn_align)]`)
LLVM uses the word "code" to refer to a particular kind of coverage mapping.
This unrelated usage of the word is confusing, and makes it harder to introduce
types whose names correspond to the LLVM classification of coverage kinds.
Get rid of `predicates_defined_on`
This is the uncontroversial part of #129532. This simply inlines the `predicates_defined_on` into into `predicates_of`. Nothing should change here logically.
Stop storing a special inner body for the coroutine by-move body for async closures
...and instead, just synthesize an item which is treated mostly normally by the MIR pipeline.
This PR does a few things:
* We synthesize a new `DefId` for the by-move body of a closure, which has its `mir_built` fed with the output of the `ByMoveBody` MIR transformation, and some other relevant queries.
* This has the `DefKind::ByMoveBody`, which we use to distinguish it from "real" bodies (that come from HIR) which need to be borrowck'd. Introduce `TyCtxt::is_synthetic_mir` to skip over `mir_borrowck` which is called by `mir_promoted`; borrowck isn't really possible to make work ATM since it heavily relies being called on a body generated from HIR, and is redundant by the construction of the by-move-body.
* Remove the special `PassManager` hacks for handling the inner `by_move_body` stored within the coroutine's mir body. Instead, this body is fed like a regular MIR body, so it's goes through all of the `tcx.*_mir` stages normally (build -> promoted -> ...etc... -> optimized) ✨.
* Remove the `InstanceKind::ByMoveBody` shim, since now we have a "regular" def id, we can just use `InstanceKind::Item`. This also allows us to remove the corresponding hacks from codegen, such as in `fn_sig_for_fn_abi` ✨.
Notable remarks:
* ~~I know it's kind of weird to be using `DefKind::Closure` here, since it's not a distinct closure but just a new MIR body. I don't believe it really matters, but I could also use a different `DefKind`... maybe one that we could use for synthetic MIR bodies in general?~~ edit: We're doing this now.
The main `arbitrary_self_types` feature gate will shortly be reused for
a new version of arbitrary self types which we are amending per [this
RFC](https://github.com/rust-lang/rfcs/blob/master/text/3519-arbitrary-self-types-v2.md).
The main amendments are:
* _do_ support `self` types which can't safely implement `Deref`
* do _not_ support generic `self` types
* do _not_ support raw pointers as `self` types.
This PR relates to the last of those bullet points: this strips pointer
support from the current `arbitrary_self_types` feature.
We expect this to cause some amount of breakage for crates using this
unstable feature to allow raw pointer self types. If that's the case, we
want to know about it, and we want crate authors to know of the upcoming
changes.
For now, this can be resolved by adding the new
`arbitrary_self_types_pointers` feature to such crates. If we determine
that use of raw pointers as self types is common, then we may maintain
that as an unstable feature even if we come to stabilize the rest of the
`arbitrary_self_types` support in future. If we don't hear that this PR
is causing breakage, then perhaps we don't need it at all, even behind
an unstable feature gate.
[Tracking issue](https://github.com/rust-lang/rust/issues/44874)
This is [step 4 of the plan outlined here](https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688)
make it possible to enable const_precise_live_drops per-function
This makes const_precise_live_drops work with rustc_allow_const_fn_unstable so that we can stabilize individual functions that rely on const_precise_live_drops.
The goal is that we can use that to stabilize some of https://github.com/rust-lang/rust/issues/67441 without having to stabilize const_precise_live_drops.
As our implementation of MCP411 nears completion and we begin to
solicit testing, it's no longer reasonable to expect testers to
type or remember `BikeshedIntrinsicFrom`. The name degrades the
ease-of-reading of documentation, and the overall experience of
using compiler safe transmute.
Tentatively, we'll instead adopt `TransmuteFrom`.
This name seems to be the one most likely to be stabilized, after
discussion on Zulip [1]. We may want to revisit the ordering of
`Src` and `Dst` before stabilization, at which point we'd likely
consider `TransmuteInto` or `Transmute`.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20should.20.60BikeshedIntrinsicFrom.60.20be.20named.3F
Convert to_llvm_features to return Option<LLVMFeature> so that it can
return None if the requested feature is not available for the current
LLVM version.
Add match rules to filter out aarch64 features not available in LLVM 17.
FEAT_FPMR has been removed from upstream LLVM as of LLVM 19.
Remove the feature from the target features list and temporarily hack
the LLVM codegen to always enable it until the minimum LLVM version is
bumped to 19.
Add SME aarch64 features already supported by LLVM and Linux.
This commit adds compiler support for the following features:
- FEAT_SME
- FEAT_SME_F16F16
- FEAT_SME_F64F64
- FEAT_SME_F8F16
- FEAT_SME_F8F32
- FEAT_SME_FA64
- FEAT_SME_I16I64
- FEAT_SME_LUTv2
- FEAT_SME2
- FEAT_SME2p1
- FEAT_SSVE_FP8DOT2
- FEAT_SSVE_FP8DOT4
- FEAT_SSVE_FP8FMA
Add various aarch64 features already supported by LLVM and Linux.
The features are marked as unstable using a newly added symbol, i.e.
aarch64_unstable_target_feature.
Additionally include some comment fixes to ensure consistency of
feature names with the Arm ARM and support for architecture version
target features up to v9.5a.
This commit adds compiler support for the following features:
- FEAT_CSSC
- FEAT_ECV
- FEAT_FAMINMAX
- FEAT_FLAGM2
- FEAT_FP8
- FEAT_FP8DOT2
- FEAT_FP8DOT4
- FEAT_FP8FMA
- FEAT_FPMR
- FEAT_HBC
- FEAT_LSE128
- FEAT_LSE2
- FEAT_LUT
- FEAT_MOPS
- FEAT_LRCPC3
- FEAT_SVE_B16B16
- FEAT_SVE2p1
- FEAT_WFxT
Add `f16` and `f128` inline ASM support for `aarch64`
Adds `f16` and `f128` inline ASM support for `aarch64`. SIMD vector types are taken from [the ARM intrinsics list](https://developer.arm.com/architectures/instruction-sets/intrinsics/#f:`@navigationhierarchiesreturnbasetype=[float]&f:@navigationhierarchieselementbitsize=[16]&f:@navigationhierarchiesarchitectures=[A64]).` Based on the work of `@lengrongfu` in #127043.
Relevant issue: #125398
Tracking issue: #116909
`@rustbot` label +F-f16_and_f128
try-job: aarch64-gnu
try-job: aarch64-apple
Add Trusty OS as tier 3 target
This PR adds support for the [Trusty secure operating system](https://source.android.com/docs/security/features/trusty) as a Tier 3 supported target. This upstreams [the patch that we have been using](https://cs.android.com/android/platform/superproject/+/master:external/rust/crates/libc/patches/trusty.patch;l=1;drc=122e586e93a534160230dc10ae3474cf31dd8f7f) internally. This also revives https://github.com/rust-lang/rust/pull/103895 which was closed due to inactivity, and is being resumed now that time allows.
And MCP has already been done for adding this platform: rust-lang/compiler-team/issues/568
# Target Tier Policy Acknowledgements
> A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.)
- Nicole LeGare (``@randomPoison)``
- Stephen Crane (``@rinon)``
- As a fallback trusty-dev-team@google.com can be contacted
> Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target.
The two new Trusty targets, `aarch64-unknown-trusty` and `armv7-unknown-trusty` both follow the existing naming convention for similar targets.
> Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it.
👍
> Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users.
There are no known legal issues or license incompatibilities.
> Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions.
👍
> Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (core for most targets, alloc for targets that can support dynamic memory allocation, std for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions.
This PR only adds the targets for the platform. `std` support will be added once platform support is added to the libc crate, which depends on the language targets being added to rustc.
> The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running binaries, or running tests (even if they do not pass), the documentation must explain how to run such binaries or tests for the target, using emulation if possible or dedicated hardware if necessary.
👍
> Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via ``@)`` to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages.
👍
> Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target.
👍
> Tier 3 targets must be able to produce assembly using at least one of rustc's supported backends from any host target. (Having support in a fork of the backend is not sufficient, it must be upstream.)
👍
rustc: Simplify getting sysroot library directory
It was very non-obvious that `sess.target_tlib_path`, `make_target_lib_path(...)`, and `sess.target_filesearch(...).search_paths()` result in the same sysroot library directory paths.
They are however, indeed the same, because `sess.target_tlib_path` is initialized to `make_target_lib_path(...)` on `Session` creation, and they are used interchangeably.
There are still some redundant calls to `make_target_lib_path` and other inconsistent ways to obtain sysroot directories, but fixing that requires some behavior changes, while this PR is a pure refactoring.
Some places in the compiler even disagree on the number of sysroots - 1 (explicit `--sysroot` *or* default sysroot), 2 (explicit `--sysroot` *and* default sysroot), or an unclear number of `sysroot_candidates` every of which is considered.
The logic currently using `sess.target_tlib_path` or equivalents assumes one sysroot.
miri weak memory emulation: put previous value into initial store buffer
Fixes https://github.com/rust-lang/miri/issues/2164 by doing a read before each atomic write so that we can initialize the store buffer. The read suppresses memory access hooks and UB exceptions, to avoid otherwise influencing the program behavior. If the read fails, we store that as `None` in the store buffer, so that when an atomic read races with the first atomic write to some memory and previously the memory was uninitialized, we can report UB due to reading uninit memory.
``@cbeuw`` this changes a bit the way we initialize the store buffers. Not sure if you still remember all this code, but if you could have a look to make sure this still makes sense, that would be great. :)
r? ``@saethlin``
simd_shuffle intrinsic: allow argument to be passed as vector
See https://github.com/rust-lang/rust/issues/128738 for context.
I'd like to get rid of [this hack](6c0b89dfac/compiler/rustc_codegen_ssa/src/mir/block.rs (L922-L935)). https://github.com/rust-lang/rust/pull/128537 almost lets us do that since constant SIMD vectors will then be passed as immediate arguments. However, simd_shuffle for some reason actually takes an *array* as argument, not a vector, so the hack is still required to ensure that the array becomes an immediate (which then later stages of codegen convert into a vector, as that's what LLVM needs).
This PR prepares simd_shuffle to also support a vector as the `idx` argument. Once this lands, stdarch can hopefully be updated to pass `idx` as a vector, and then support for arrays can be removed, which finally lets us get rid of that hack.
Remove `ParamMode::ExplicitNamed`
This was introduced as a hack to improve a diagnostics suggestion in #61679. It was subsequently broken, but also it was an incomplete hack that I don't believe we need to support, so let's just remove it.
Remove Duplicate E0381 Label
Aims to resolve https://github.com/rust-lang/rust/issues/129274, and adds a test for the case.
Essentially, we are duplicating this span for some reason. For now, I'm just using a set to collect the spans rather than the vec. I imagine there's probably no real reason to inspect duplicates in this area, but if I'm wrong I can adjust to collect "seen spans" in just the point where this label is applied.
I'm not sure why it's producing duplicate spans. Looks like this has been this way for a while? I think it gives the duplicate label on 1.75.0 for example.
Do not ICE on non-ADT rcvr type when looking for crate version collision
When looking for multiple versions of the same crate, do not blindly construct the receiver type.
Follow up to #128786.
Fixes#129205Fixes#129216
Document & implement the transmutation modeled by `BikeshedIntrinsicFrom`
Documents that `BikeshedIntrinsicFrom` models transmute-via-union, which is slightly more expressive than the transmute-via-cast implemented by `transmute_copy`. Additionally, we provide an implementation of transmute-via-union as a method on the `BikeshedIntrinsicFrom` trait with additional documentation on the boundary between trait invariants and caller obligations.
Whether or not transmute-via-union is the right kind of transmute to model remains up for discussion [1]. Regardless, it seems wise to document the present behavior.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20'kind'.20of.20transmute.20to.20model.3F/near/426331967
Tracking Issue: https://github.com/rust-lang/rust/issues/99571
r? `@compiler-errors`
cc `@scottmcm,` `@Lokathor`
Add `#[warn(unreachable_pub)]` to a bunch of compiler crates
By default `unreachable_pub` identifies things that need not be `pub` and tells you to make them `pub(crate)`. But sometimes those things don't need any kind of visibility. So they way I did these was to remove the visibility entirely for each thing the lint identifies, and then add `pub(crate)` back in everywhere the compiler said it was necessary. (Or occasionally `pub(super)` when context suggested that was appropriate.) Tedious, but results in more `pub` removal.
There are plenty more crates to do but this seems like enough for a first PR.
r? `@compiler-errors`
Tie `impl_trait_overcaptures` lint to Rust 2024
The `impl_trait_overcaptures` lint is part of the migration to Rust 2024 and the Lifetime Capture Rules 2024. Now that we've stabilized precise capturing (RFC 3617), let's tie this lint to the `rust_2024_compatibility` lint group.
Tracking:
- https://github.com/rust-lang/rust/issues/117587
r? `@compiler-errors`
mv `build_reduced_graph_for_external_crate_res` into Resolver
`build_reduced_graph_for_external_crate_res` is only related to `Resolver`, so move it there.
r? `@petrochenkov`
const checking: properly compute the set of transient locals
For const-checking the MIR of a const/static initializer, we have to know the set of "transient" locals. The reason for this is that creating a mutable (or interior mutable) reference to a transient local is "safe" in the sense that this reference cannot possibly end up in the final value of the const -- even if it is turned into a raw pointer and stored in a union, we will see that pointer during interning and reliably reject it as dangling.
So far, we determined the set of transient locals as "locals that have a `StorageDead` somewhere". But that's not quite right -- if we had MIR like
```rust
StorageLive(_5);
StorageDead(_5);
StorageLive(_5);
// no further storage annotations for _5
```
Then we'd consider `_5` to be "transient", but it is not actually transient.
We do not currently generate such MIR, but I feel uneasy relying on subtle invariants like this. So this PR implements a proper analysis for computing the set of "transient" locals: a local is "transient" if it is guaranteed dead at all `Return` terminators.
Cc `@cjgillot`
The `impl_trait_overcaptures` lint is part of the migration to Rust
2024 and the Lifetime Capture Rules 2024. Now that we've stabilized
precise capturing (RFC 3617), let's tie this lint to the
`rust_2024_compatibility` lint group.
add back test for stable-const-can-only-call-stable-const
This got accidentally removed in https://github.com/rust-lang/rust/pull/128596 (file `tests/ui/internal/internal-unstable-const.rs`). The test has little to do with "allow internal unstable" though, so add it in a file that already tests various const stability things.
Also tweak the help that suggests to add `rustc_allow_const_fn_unstable` to make it clear that this needs team approval, since it is a fairly big gun.
Use `FxHasher` on new solver unconditionally
r? lqd
This should actually fix the inference problem in ad855fe6db, since `HashSet::default` was not inferring the hasher when `HashSet` was coming from the stdlib due to the way that defaulted types/inference vars work. You could cherry-pick this on top of your PR alternatively.
rustdoc: clean up tuple <-> primitive conversion docs
This adds a minor missing feature to `fake_variadic`, so that it can render `impl From<(T,)> for [T; 1]` correctly.
Remove redundant flags from `lower_ty_common` that can be inferred from the HIR
...and then get rid of `lower_ty_common`.
r? ``@fmease`` or re-roll if you're busy!
Use subtyping for `UnsafeFnPointer` coercion, too
I overlooked this in #129059, which changed MIR typechecking to use subtyping for other fn pointer coercions.
Fixes#129285
Make `rustc_type_ir` build on stable
This PR fixes a handful of issues that appear in `rustc_type_ir` when trying to build the new solver on stable.
r? ```@compiler-errors```
```@bors``` rollup
library: Move unstable API of new_uninit to new features
- `new_zeroed` variants move to `new_zeroed_alloc`
- the `write` fn moves to `box_uninit_write`
The remainder will be stabilized in upcoming patches, as it was decided to only stabilize `uninit*` and `assume_init`.
Print the generic parameter along with the variance in dumps.
This allows to make sure we are testing what we think we are testing.
While the tests are correct, I discovered that opaque duplicated args are in the reverse declaration order.
Add a special case for `CStr`/`CString` in the `improper_ctypes` lint
Revives #120176. Just needed to bless a test and fix an argument, but seemed reasonable to me otherwise.
Instead of saying to "consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct", we now tell users to "Use `*const ffi::c_char` instead, and pass the value from `CStr::as_ptr()`" when the type involved is a `CStr` or a `CString`.
The suggestion is not made for `&mut CString` or `*mut CString`.
r? ``````@cjgillot`````` (since you were the reviewer of the original PR #120176, but feel free to reroll)
Detect `*` operator on `!Sized` expression
The suggestion is new:
```
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/unsized-str-in-return-expr-arg-and-local.rs:15:9
|
LL | let x = *"";
| ^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `str`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
help: references to `!Sized` types like `&str` are `Sized`; consider not dereferencing the expression
|
LL - let x = *"";
LL + let x = "";
|
```
Fix#128199.
Retroactively feature gate `ConstArgKind::Path`
This puts the lowering introduced by #125915 under a feature gate until we fix the regressions introduced by it. Alternative to whole sale reverting the PR since it didn't seem like a very clean revert and I think this is generally a step in the right direction and don't want to get stuck landing and reverting the PR over and over :)
cc #129137 ``@camelid,`` tests taken from there. beta is branching soon so I think it makes sense to not try and rush that fix through since it wont have much time to bake and if it has issues we can't simply revert it on beta.
Fixes#128016
make writes_through_immutable_pointer a hard error
This turns the lint added in https://github.com/rust-lang/rust/pull/118324 into a hard error. This has been reported in cargo's future-compat reports since Rust 1.76 (released in February). Given that const_mut_refs is still unstable, it should be impossible to even hit this error on stable: we did accidentally stabilize some functions that can cause this error, but that got reverted in https://github.com/rust-lang/rust/pull/117905. Still, let's do a crater run just to be sure.
Given that this should only affect unstable code, I don't think it needs an FCP, but let's Cc ``@rust-lang/lang`` anyway -- any objection to making this unambiguous UB into a hard error during const-eval? This can be viewed as part of https://github.com/rust-lang/rust/pull/129195 which is already nominated for discussion.
- `new_zeroed` variants move to `new_zeroed_alloc`
- the `write` fn moves to `box_uninit_write`
The remainder will be stabilized in upcoming patches, as
it was decided to only stabilize `uninit*` and `assume_init`.
By keeping track of attributes that have been previously processed.
This fixes the `macro-rules-derive-cfg.stdout` test, and is necessary
for #124141 which removes nonterminals.
Also shrink the `SmallVec` inline size used in `IntervalSet`. 2 gives
slightly better perf than 4 now that there's an `IntervalSet` in
`Parser`, which is cloned reasonably often.
Documents that `BikeshedIntrinsicFrom` models transmute-via-union,
which is slightly more expressive than the transmute-via-cast
implemented by `transmute_copy`. Additionally, we provide an
implementation of transmute-via-union as a method on the
`BikeshedIntrinsicFrom` trait with additional documentation on
the boundary between trait invariants and caller obligations.
Whether or not transmute-via-union is the right kind of transmute
to model remains up for discussion [1]. Regardless, it seems wise
to document the present behavior.
[1] https://rust-lang.zulipchat.com/#narrow/stream/216762-project-safe-transmute/topic/What.20'kind'.20of.20transmute.20to.20model.3F/near/426331967
Rollup of 9 pull requests
Successful merges:
- #128511 (Document WebAssembly target feature expectations)
- #129243 (do not build `cargo-miri` by default on stable channel)
- #129263 (Add a missing compatibility note in the 1.80.0 release notes)
- #129276 (Stabilize feature `char_indices_offset`)
- #129350 (adapt integer comparison tests for LLVM 20 IR changes)
- #129408 (Fix handling of macro arguments within the `dropping_copy_types` lint)
- #129426 (rustdoc-search: use tighter json for names and parents)
- #129437 (Fix typo in a help diagnostic)
- #129457 (kobzol vacation)
r? `@ghost`
`@rustbot` modify labels: rollup
Fix handling of macro arguments within the `dropping_copy_types` lint
This PR fixes the handling of spans with different context (aka macro arguments) than the primary expression within the different `{drop,forget}ing_copy_types` and `{drop,forget}ing_references` lints.
<details>
<summary>Before</summary>
```
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
--> drop_writeln.rs:5:5
|
5 | drop(writeln!(&mut msg, "test"));
| ^^^^^--------------------------^
| |
| argument has type `Result<(), std::fmt::Error>`
|
= note: `#[warn(dropping_copy_types)]` on by default
help: use `let _ = ...` to ignore the expression or result
--> /home/[..]/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/macros/mod.rs:688:9
|
68| let _ =
| ~~~~~~~
```
</details>
<details>
<summary>With this PR</summary>
```
warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
--> drop_writeln.rs:5:5
|
5 | drop(writeln!(&mut msg, "test"));
| ^^^^^--------------------------^
| |
| argument has type `Result<(), std::fmt::Error>`
|
= note: `#[warn(dropping_copy_types)]` on by default
help: use `let _ = ...` to ignore the expression or result
|
5 - drop(writeln!(&mut msg, "test"));
5 + let _ = writeln!(&mut msg, "test");
|
```
</details>
``````@rustbot`````` label +L-dropping_copy_types
In a case like this:
```
mod a {
mod b {
#[cfg_attr(unix, inline)]
fn f() {
#[cfg_attr(linux, inline)]
fn g1() {}
#[cfg_attr(linux, inline)]
fn g2() {}
}
}
}
```
We currently end up with the following replacement ranges.
- The lazy tokens for `f` has replacement ranges for `g1` and `g2`.
- The lazy tokens for `a` has replacement ranges for `f`, `g1`, and
`g2`.
I.e. the replacement ranges for `g1` and `g2` are duplicated. In
general, replacement ranges for inner AST nodes are duplicated up the
chain for each nested `collect_tokens` call. And the code that processes
the replacements is careful about the ordering in which the replacements
are applied, to ensure that inner replacements are applied before outer
replacements.
But all of this is unnecessary. If you apply an inner replacement and
then an outer replacement, the outer replacement completely overwrites
the inner replacement.
This commit avoids the duplication by removing replacements from
`self.capture_state.parser_replacements` when they are used. (The effect
on the example above is that the lazy tokesn for `a` no longer include
replacement ranges for `g1` and `g2`.) This eliminates the possibility
of nested replacements on individual AST nodes, which avoids the need
for careful ordering of replacements.
This example triggers an assertion failure:
```
fn f() -> u32 {
#[cfg_eval] #[cfg(not(FALSE))] 0
}
```
The sequence of events:
- `configure_annotatable` calls `parse_expr_force_collect`, which calls
`collect_tokens`.
- Within that, we end up in `parse_expr_dot_or_call`, which again calls
`collect_tokens`.
- The return value of the `f` call is the expression `0`.
- This inner call collects tokens for `0` (parser range 10..11) and
creates a replacement covering `#[cfg(not(FALSE))] 0` (parser range
0..11).
- We return to the outer `collect_tokens` call. The return value of the
`f` call is *again* the expression `0`, again with the range 10..11,
but the replacement from earlier covers the range 0..11. The code
mistakenly assumes that any attributes from an inner `collect_tokens`
call fit entirely within the body of the result of an outer
`collect_tokens` call. So it adjusts the replacement parser range
0..11 to a node range by subtracting 10, resulting in -10..1. This is
an invalid range and triggers an assertion failure.
It's tricky to follow, but basically things get complicated when an AST
node is returned from an inner `collect_tokens` call and then returned
again from an outer `collect_token` node without being wrapped in any
kind of additional layer.
This commit changes `collect_tokens` to return early in some extra cases,
avoiding the construction of lazy tokens. In the example above, the
outer `collect_tokens` returns earlier because the `0` token already has
tokens and `self.capture_state.capturing` is `Capturing::No`. This early
return avoids the creation of the invalid range and the assertion
failure.
Fixes#129166. Note: these invalid ranges have been happening for a long
time. #128725 looks like it's at fault only because it introduced the
assertion that catches the invalid ranges.
Allow rust staticlib to work with MSVC's /WHOLEARCHIVE
This fixes#129020 by renaming the `__NULL_IMPORT_DESCRIPTOR` to prevent conflicts.
try-job: dist-i686-msvc
Rollup of 8 pull requests
Successful merges:
- #128432 (WASI: forbid `unsafe_op_in_unsafe_fn` for `std::{os, sys}`)
- #129373 (Add missing module flags for CFI and KCFI sanitizers)
- #129374 (Use `assert_unsafe_precondition!` in `AsciiChar::digit_unchecked`)
- #129376 (Change `assert_unsafe_precondition` docs to refer to `check_language_ub`)
- #129382 (Add `const_cell_into_inner` to `OnceCell`)
- #129387 (Advise against removing the remaining Python scripts from `tests/run-make`)
- #129388 (Do not rely on names to find lifetimes.)
- #129395 (Pretty-print own args of existential projections (dyn-Trait w/ GAT constraints))
r? `@ghost`
`@rustbot` modify labels: rollup
Pretty-print own args of existential projections (dyn-Trait w/ GAT constraints)
Previously we would just drop them. This bug isn't that significant as it can only be triggered by user code that constrains GATs inside trait object types which is currently gated under the interim feature `generic_associated_types_extended` (whose future is questionable) or on stable if the GATs are 'disabled' in dyn-Trait via `where Self: Sized` (in which case the assoc type bindings get ignored anyway (and trigger the warn-by-default lint `unused_associated_type_bounds`)), so yeah.
Affects diagnostic output and output of `std::any::type_name{_of_val}`.
Do not rely on names to find lifetimes.
For some reason, we were trying to find the lifetime parameter from its name, instead of using the def_id we have.
This PR uses it instead. This changes some ui tests, I think to be more sensible.
Add missing module flags for CFI and KCFI sanitizers
Set the cfi-normalize-integers and kcfi-offset module flags when Control-Flow Integrity sanitizers are used, so functions generated by the LLVM backend use the same CFI/KCFI options as rustc.
cfi-normalize-integers tells LLVM to also use integer normalization for generated functions when -Zsanitizer-cfi-normalize-integers is used.
kcfi-offset specifies the number of prefix nops between the KCFI type hash and the function entry when -Z patchable-function-entry is used. Note that LLVM assumes all indirectly callable functions use the same number of prefix NOPs with -Zsanitizer=kcfi.
Set the cfi-normalize-integers and kcfi-offset module flags when
Control-Flow Integrity sanitizers are used, so functions generated by
the LLVM backend use the same CFI/KCFI options as rustc.
cfi-normalize-integers tells LLVM to also use integer normalization
for generated functions when -Zsanitizer-cfi-normalize-integers is
used.
kcfi-offset specifies the number of prefix nops between the KCFI
type hash and the function entry when -Z patchable-function-entry is
used. Note that LLVM assumes all indirectly callable functions use the
same number of prefix NOPs with -Zsanitizer=kcfi.
llvm-wrapper: adapt for LLVM 20 API changes
No functional changes intended.
Adapts llvm-wrapper for the LLVM commits 0f22d47a7a and d6d8243dcd.
`@rustbot` label: +llvm-main
r? `@nikic`
bump conflicting_repr_hints lint to be shown in dependencies
This has been a future compatibility lint for years, let's bump it up to be shown in dependencies (so that hopefully we can then make it a hard error fairly soon).
Cc https://github.com/rust-lang/rust/issues/68585
Point at explicit `'static` obligations on a trait
Given `trait Any: 'static` and a `struct` with a `Box<dyn Any + 'a>` field, point at the `'static` bound in `Any` to explain why `'a: 'static`.
```
error[E0478]: lifetime bound not satisfied
--> f202.rs:2:12
|
2 | value: Box<dyn std::any::Any + 'a>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> f202.rs:1:14
|
1 | struct Hello<'a> {
| ^^
note: but lifetime parameter must outlive the static lifetime
--> /home/gh-estebank/rust/library/core/src/any.rs:113:16
|
113 | pub trait Any: 'static {
| ^^^^^^^
```
Partially address #33652.
Improve diagnostic-related lints: `untranslatable_diagnostic` & `diagnostic_outside_of_impl`
Summary:
- Made `untranslatable_diagnostic` point to problematic arguments instead of the function call
(I found this misleading while working on some `A-translation` PRs: my first impression was that
the methods themselves were not translation-aware and needed to be changed,
while in reality the problem was with the hardcoded strings passed as arguments).
- Made the shared pass of `untranslatable_diagnostic` & `diagnostic_outside_of_impl` more efficient.
`@rustbot` label D-imprecise-spans A-translation
use old ctx if has same expand environment during decode span
Fixes#112680
The root reason why #112680 failed with incremental compilation on the second attempt is the difference in `opaque` between the span of the field [`ident`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir_typeck/src/expr.rs#L2348) and the span in the incremental cache at `tcx.def_ident_span(field.did)`.
- Let's call the span of `ident` as `span_a`, which is generated by [`apply_mark_internal`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L553-L554). Its content is similar to:
```rs
span_a_ctx -> SyntaxContextData {
opaque: span_a_ctx,
opaque_and_semitransparent: span_a_ctx,
// ....
}
```
- And call the span of `tcx.def_ident_span` as `span_b`, which is generated by [`decode_syntax_context`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/hygiene.rs#L1390). Its content is:
```rs
span_b_ctx -> SyntaxContextData {
opaque: span_b_ctx,
// note `span_b_ctx` is not same as `span_a_ctx`
opaque_and_semitransparent: span_b_ctx,
// ....
}
```
Although they have the same `parent` (both refer to the root) and `outer_expn`, I cannot find the specific connection between them. Therefore, I chose a solution that may not be the best: give up the incremental compile cache to ensure we can use `span_a` in this case.
r? `@petrochenkov` Do you have any advice on this? Or perhaps this solution is acceptable?