Rollup of 6 pull requests
Successful merges:
- rust-lang/rust#138016 (Added `Clone` implementation for `ChunkBy`)
- rust-lang/rust#141162 (refactor `AttributeGate` and `rustc_attr!` to emit notes during feature checking)
- rust-lang/rust#141474 (Add `ParseMode::Diagnostic` and fix multiline spans in diagnostic attribute lints)
- rust-lang/rust#141947 (Specify that "option-like" enums must be `#[repr(Rust)]` to be ABI-compatible with their non-1ZST field.)
- rust-lang/rust#142252 (Improve clarity of `core::sync::atomic` docs about "Considerations" in regards to CAS operations)
- rust-lang/rust#142337 (miri: add flag to suppress float non-determinism)
r? `@ghost`
`@rustbot` modify labels: rollup
assert more in release in `rustc_ast_lowering`
My understanding of the compiler's architecture is that in the `ast_lowering` crate, we are constructing the HIR as a one-time thing per crate. This is after tokenizing, parsing, resolution, expansion, possible reparsing, reresolution, reexpansion, and so on. In other words, there are many reasons that perf-focused PRs spend a lot of time touching `rustc_parse`, `rustc_expand`, `rustc_ast`, and then `rustc_hir` and "onwards", but `ast_lowering` is a little bit of an odd duck.
In this crate, we have a number of debug assertions. Some are clearly expensive checks that seem like they are prohibitive to run in actual optimized compiler builds, but then there are a number that are simple asserts on integer equalities, `is_empty`, or the like. I believe we should do some of them even in release builds, because the correctness gain is worth the performance cost: almost zero.
add `extern "custom"` functions
tracking issue: rust-lang/rust#140829
previous discussion: https://github.com/rust-lang/rust/issues/140566
In short, an `extern "custom"` function is a function with a custom ABI, that rust does not know about. Therefore, such functions can only be defined with `#[unsafe(naked)]` and `naked_asm!`, or via an `extern "C" { /* ... */ }` block. These functions cannot be called using normal rust syntax: calling them can only be done from inline assembly.
The motivation is low-level scenarios where a custom calling convention is used. Currently, we often pick `extern "C"`, but that is a lie because the function does not actually respect the C calling convention.
At the moment `"custom"` seems to be the name with the most support. That name is not final, but we need to pick something to actually implement this.
r? `@traviscross`
cc `@tgross35`
try-job: x86_64-apple-2
retpoline and retpoline-external-thunk flags (target modifiers) to enable retpoline-related target features
`-Zretpoline` and `-Zretpoline-external-thunk` flags are target modifiers (tracked to be equal in linked crates).
* Enables target features for `-Zretpoline-external-thunk`:
`+retpoline-external-thunk`, `+retpoline-indirect-branches`, `+retpoline-indirect-calls`.
* Enables target features for `-Zretpoline`:
`+retpoline-indirect-branches`, `+retpoline-indirect-calls`.
It corresponds to clang -mretpoline & -mretpoline-external-thunk flags.
Also this PR forbids to specify those target features manually (warning).
Issue: rust-lang/rust#116852
intrinsics: rename min_align_of to align_of
Now that `pref_align_of` is gone (https://github.com/rust-lang/rust/pull/141803), we can give the intrinsic backing `align_of` its proper name.
r? `@workingjubilee` or `@bjorn3`
[AIX] strip underlying xcoff object
When stripping, we need to strip the archive member first before archiving. Otherwise, the shared library remain untouched, only the archive symbol table will be modified.
Tracking the old name of renamed unstable library features
This PR resolves the first problem of rust-lang/rust#141617 : tracking renamed unstable features. The first commit is to add a ui test, and the second one tracks the changes. I will comment on the code for clarification.
r? `@jdonszelmann`
There have been a lot of PR's reviewed by you lately, thanks for your time!
cc `@jyn514`
Introduce `-Zmacro-stats`
Introduce `-Zmacro-stats`.
It collects data about macro expansions and prints them in a table after expansion finishes. It's very useful for detecting macro bloat, especially for proc macros.
r? `@petrochenkov`
Implement asymmetrical precedence for closures and jumps
I have been through a series of asymmetrical precedence designs in Syn, and finally have one that I like and is worth backporting into rustc. It is based on just 2 bits of state: `next_operator_can_begin_expr` and `next_operator_can_continue_expr`.
Asymmetrical precedence is the thing that enables `(return 1) + 1` to require parentheses while `1 + return 1` does not, despite `+` always having stronger precedence than `return` [according to the Rust Reference](https://doc.rust-lang.org/1.83.0/reference/expressions.html#expression-precedence). This is facilitated by `next_operator_can_continue_expr`.
Relatedly, it is the thing that enables `(return) - 1` to require parentheses while `return + 1` does not, despite `+` and `-` having exactly the same precedence. This is facilitated by `next_operator_can_begin_expr`.
**Example:**
```rust
macro_rules! repro {
($e:expr) => {
$e - $e;
$e + $e;
};
}
fn main() {
repro!{return}
repro!{return 1}
}
```
`-Zunpretty=expanded` **Before:**
```console
fn main() {
(return) - (return);
(return) + (return);
(return 1) - (return 1);
(return 1) + (return 1);
}
```
**After:**
```console
fn main() {
(return) - return;
return + return;
(return 1) - return 1;
(return 1) + return 1;
}
```
compiler: Ease off the accelerator on `unsupported_calling_conventions`
This is to give us more time to discuss rust-lang/rust#142330 without the ecosystem having an anxiety attack. I have withdrawn `unsupported_calling_conventions` from report-in-deps
I believe we should consider this a simple suspension of the decision in rust-lang/rust#141435 to start this process, rather than a reversal. That is, we may continue with linting again. But I believe we are about to get a... reasonable amount of feedback just from currently available information and should allow ourselves time to process it.
Rollup of 9 pull requests
Successful merges:
- rust-lang/rust#134536 (Lint on fn pointers comparisons in external macros)
- rust-lang/rust#141069 (Suggest mut when possbile for temporary value dropped while borrowed)
- rust-lang/rust#141934 (resolve: Tweak `private_macro_use` lint to be compatible with upcoming macro prelude changes)
- rust-lang/rust#142034 (Detect method not being present that is present in other tuple types)
- rust-lang/rust#142402 (chore(doctest): Remove redundant blank lines)
- rust-lang/rust#142406 (Note when enum variants shadow an associated function)
- rust-lang/rust#142407 (Remove bootstrap adhoc group)
- rust-lang/rust#142408 (Add myself (WaffleLapkin) to review rotation)
- rust-lang/rust#142418 (Remove lower_arg_ty as all callers were passing `None`)
r? `@ghost`
`@rustbot` modify labels: rollup
```
error: cannot find attribute `empty_helper` in this scope
--> $DIR/derive-helper-legacy-limits.rs:17:3
|
LL | #[empty_helper]
| ^^^^^^^^^^^^
|
help: `empty_helper` is an attribute that can be used by the derive macro `Empty`, you might be missing a `derive` attribute
|
LL + #[derive(Empty)]
LL | struct S2;
|
```
Look at proc-macro attributes when encountering unknown attribute
```
error: cannot find attribute `sede` in this scope
--> src/main.rs:18:7
|
18 | #[sede(untagged)]
| ^^^^
|
help: the derive macros `Serialize` and `Deserialize` accept the similarly named `serde` attribute
|
18 | #[serde(untagged)]
| ~~~~~
error: cannot find attribute `serde` in this scope
--> src/main.rs:12:7
|
12 | #[serde(untagged)]
| ^^^^^
|
= note: `serde` is in scope, but it is a crate, not an attribute
help: `serde` is an attribute that can be used by the derive macros `Serialize` and `Deserialize`, you might be missing a `derive` attribute
|
10 | #[derive(Serialize, Deserialize)]
|
```
Detect method not being present that is present in other tuple types
When a method is not present because of a trait bound not being met, and that trait bound is on a tuple, we check if making the tuple have no borrowed types makes the method to be found and highlight it if it does. This is a common problem for Bevy in particular and ORMs in general.
<img width="1166" alt="Screenshot 2025-06-04 at 10 38 24 AM" src="https://github.com/user-attachments/assets/d257c9ea-c2d7-42e7-8473-8b93aa54b8e0" />
Address rust-lang/rust#141258. I believe that more combination of cases in the tuple types should be handled (like adding borrows and checking when a specific type needs to not be a borrow while the rest stay the same), but for now this handles the most common case.
resolve: Tweak `private_macro_use` lint to be compatible with upcoming macro prelude changes
Unblocks https://github.com/rust-lang/rust/pull/139493.
Zulip thread requesting help - [#t-compiler/help > Help requested for effects of #139493](https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/Help.20requested.20for.20effects.20of.20.23139493/with/514653911).
This PR by itself shouldn't cause any observable changes, its only observable effect is that the prelude changes from https://github.com/rust-lang/rust/pull/139493 will no longer cause regressions in tests like `tests/ui/imports/issue-119369.rs` or `tests/ui/extern/issue-80074.rs`.
This is achieved by moving the "is this thing in stdlib prelude" check from an early point (`fn process_macro_use_imports`) to a later point (`fn record_use_inner`), at which the stdlib prelude is already populated and can be inspected.
(The `is_builtin_macro` check is subsumed by the stdlib prelude check, all built-in macros go through the stdlib prelude anyway.)
Lint on fn pointers comparisons in external macros
This PR extends the recently stabilized `unpredictable_function_pointer_comparisons` lint ~~to also lint on `Option<{function pointer}>` and~~ as well as linting in external macros (as to catch `assert_eq!` and others).
```rust
assert_eq!(Some::<FnPtr>(func), Some(func as unsafe extern "C" fn()));
//~^ WARN function pointer comparisons
#[derive(PartialEq, Eq)]
struct A {
f: fn(),
//~^ WARN function pointer comparisons
}
```
Fixes https://github.com/rust-lang/rust/issues/134527
Infrastructure for lints during attribute parsing, specifically duplicate usages of attributes
r? `@oli-obk`
This PR adds a new field to OwnerInfo to buffer lints which are generated during attribute parsing and ast lowering in general. They can't be emitted at this stage because at that point there's no HIR yet, and early lints are already emitted.
This also adds the generic `S: Stage` to attribute parsers. Currently we don't emit any lints during early attribute parsing, but if we ever want to that logic will be different. That's because there we don't have hir ids yet, while at the same time still having access to node ids and early lints. Even though that logic isn't completely there in this PR (no worries, we don't use it), that's why the parameter is there.
With this PR, we also add 2 associated consts to `SingleAttributeParser`. Those determine what logic should be applied when finding a duplicate attribute.
This PR was getting pretty large, so the first code using this logic is in rust-lang/rust#138165. This code is all new things that weren't possible before so it also doesn't break any behaviour. However, some of it will be dead code right now. I recommend reviewing both before merging, though in some sense that doubles the size of the review again, and the other PR might be more controversial. Let me know how you want to do this `@oli-obk`
Add `ParseMode::Diagnostic` and fix multiline spans in diagnostic attribute lints
Best viewed commit by commit.
The first commit is a test, the commits following that are small refactors to `rustc_parse_format`. Originally I wanted to do a much larger change (doing these smaller fixes first would have that made easier to review), but ended up doing something else instead.
An observable change from this is that the diagnostic attribute no longer tries to parse align/fill/width/etc parameters. For an example (see also test changes), a string like `"{Self:!}"` no longer says "missing '}'", instead it says that format parameters are not allowed. It'll now also format the string as if the user wrote just `"{Self}"`
refactor `AttributeGate` and `rustc_attr!` to emit notes during feature checking
First commit changes the following:
- `AttributeGate ` from an enum with (four) tuple fields to (five) named fields
- adds a `notes` fields that is emitted as notes in the `PostExpansionVisitor` pass
- removes the `this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date` note if the feature gate is `rustc_attrs`.
- various phrasing changes and touchups
- and finally, the reason why I went down this path to begin with: tell people they can use the diagnostic namespace when they hit the rustc_on_unimplemented feature gate 🙈
Second commit removes unused machinery for deprecated attributes
Apply nested goals certainty to `InspectGoals` for normalizes-to
...so that normalizes-to goals don't have `Certainty::Yes` even if they have nested goals which don't hold.
r? lcnr
It collects data about macro expansions and prints them in a table after
expansion finishes. It's very useful for detecting macro bloat,
especially for proc macros.
Details:
- It measures code snippets by pretty-printing them and then measuring
lines and bytes. This required a bunch of additional pretty-printing
plumbing, in `rustc_ast_pretty` and `rustc_expand`.
- The measurement is done in `MacroExpander::expand_invoc`.
- The measurements are stored in `ExtCtxt::macro_stats`.