de-duplicate condition scoping logic between AST→HIR lowering and `ScopeTree` construction
There was some overlap between `rustc_ast_lowering::LoweringContext::lower_cond` and `rustc_hir_analysis::check::region::resolve_expr`, so I've removed the former and migrated its logic to the latter, with some simplifications.
Consequences:
- For `while` and `if` expressions' `let`-chains, this changes the `HirId`s for the `&&`s to properly correspond to their AST nodes. This is how guards were handled already.
- This makes match guards share previously-duplicated logic with `if`/`while` expressions. This will also be used by guard pattern[^1] guards.
- Aside from legacy syntax extensions (e.g. some builtin macros) that directly feed AST to the compiler, it's currently impossible to put attributes directly on `&&` operators in `let` chains[^2]. Nonetheless, attributes on `&&` operators in `let` chains in `if`/`while` expression conditions are no longer silently ignored and will be lowered.
- This no longer wraps conditions in `DropTemps`, so the HIR and THIR will be slightly smaller.
- `DesugaringKind::CondTemporary` is now gone. It's no longer applied to any spans, and all uses of it were dead since they were made to account for `if` and `while` being desugared to `match` on a boolean scrutinee.
- Should be a marginal perf improvement beyond that due to leveraging [`ScopeTree` construction](5e749eb66f/compiler/rustc_hir_analysis/src/check/region.rs (L312-L355))'s clever handling of `&&` and `||`:
- This removes some unnecessary terminating scopes that were placed around top-level `&&` and `||` operators in conditions. When lowered to MIR, logical operator chains don't create intermediate boolean temporaries, so there's no temporary to drop. The linked snippet handles wrapping the operands in terminating scopes as necessary, in case they create temporaries.
- The linked snippet takes care of letting `let` temporaries live and terminating other operands, so we don't need separate traversals of `&&` chains for that.
[^1]: rust-lang/rust#129967
[^2]: Case-by-case, here's my justification: `#[attr] e1 && e2` applies the attribute to `e1`. In `#[attr] (e1 && e2)` , the attribute is on the parentheses in the AST, plus it'd fail to parse if `e1` or `e2` contains a `let`. In `#[attr] expands_to_let_chain!()`, the attribute would already be ignored (rust-lang/rust#63221) and it'd fail to parse anyway; even if the expansion site is a condition, the expansion wouldn't be parsed with `Restrictions::ALLOW_LET`. If it *was* allowed, the notion of a "reparse context" from https://github.com/rust-lang/rust/issues/61733#issuecomment-509626449 would be necessary in order to make `let`-chains left-associative; multiple places in the compiler assume they are.
Split up the `unknown_or_malformed_diagnostic_attributes` lint
This splits up the lint into the following lint group:
- `unknown_diagnostic_attributes` - triggers if the attribute is unknown to the current compiler
- `misplaced_diagnostic_attributes` - triggers if the attribute exists but it is not placed on the item kind it's meant for
- `malformed_diagnostic_attributes` - triggers if the attribute's syntax or options are invalid
- `malformed_diagnostic_format_literals` - triggers if the format string literal is invalid, for example if it has unpaired curly braces or invalid parameters
- this pr doesn't create it, but future lints for things like deprecations can also go here.
This PR does not start emitting lints in places that previously did not.
## Motivation
I want to have finer control over what `unknown_or_malformed_diagnostic_attributes` does
I have a project with fairly low msrv that is/will have a lower msrv than future diagnostic attributes. So lints will be emitted when I or others compile it on a lower msrv.
At this time, there are two options to silence these lints:
- `#[allow(unknown_or_malformed_diagnostic_attributes)]` - this risks diagnostic regressions if I (or others) mess up using the attribute, or if the attribute's syntax ever changes.
- write a build script to detect the compiler version and emit cfgs, and then conditionally enable the attribute:
```rust
#[cfg_attr(rust_version_99, diagnostic::new_attr_in_rust_99(thing = ..))]`
struct Foo;
```
or conditionally `allow` the lint:
```rust
// lib.rs
#![cfg_attr(not(current_rust), allow(unknown_or_malformed_diagnostic_attributes))]
```
I like to avoid using build scripts if I can, so the following works much better for me. That is what this PR will let me do in the future:
```rust
#[allow(unknown_diagnostic_attribute, reason = "attribute came out in rust 1.99 but msrv is 1.70")]
#[diagnostic::new_attr_in_rust_99(thing = ..)]`
struct Foo;
Rollup of 9 pull requests
Successful merges:
- rust-lang/rust#143403 (Port several trait/coherence-related attributes the new attribute system)
- rust-lang/rust#143633 (fix: correct assertion to check for 'noinline' attribute presence before removal)
- rust-lang/rust#143647 (Clarify and expand documentation for std::sys_common dependency structure)
- rust-lang/rust#143716 (compiler: doc/comment some codegen-for-functions interfaces)
- rust-lang/rust#143747 (Add target maintainer information for aarch64-unknown-linux-musl)
- rust-lang/rust#143759 (Fix typos in function names in the `target_feature` test)
- rust-lang/rust#143767 (Bump `src/tools/x` to Edition 2024 and some cleanups)
- rust-lang/rust#143769 (Remove support for SwitchInt edge effects in backward dataflow)
- rust-lang/rust#143770 (build-helper: clippy fixes)
r? `@ghost`
`@rustbot` modify labels: rollup
Update cargo
14 commits in 930b4f62cfcd1f0eabdb30a56d91bf6844b739bf..eabb4cd923deb73e714f7ad3f5234d68ca284dbe
2025-06-28 14:58:43 +0000 to 2025-07-09 22:07:55 +0000
- feat: Implementation and tests for `multiple-build-scripts` (rust-lang/cargo#15704)
- perf: Speed up TOML parsing by upgrading toml (rust-lang/cargo#15736)
- Mark cachelock tests that rely on interprocess blocking behaviour as unsupported on AIX. (rust-lang/cargo#15734)
- feat(publish): Stabilize multi-package publishing (rust-lang/cargo#15636)
- Update to Rust 2024 (rust-lang/cargo#15732)
- Clarify package ID specifications in SBOMs are fully qualified (rust-lang/cargo#15731)
- chore(deps): update cargo-semver-checks to v0.42.0 (rust-lang/cargo#15730)
- test: Switch config tests to use snapshots (rust-lang/cargo#15729)
- implement package feature unification (rust-lang/cargo#15684)
- chore: Upgrade dependencies (rust-lang/cargo#15722)
- Report valid file name when we can't find a build target for `name = "foo.rs"` (rust-lang/cargo#15707)
- chore(release): Publish build-rs on release (rust-lang/cargo#15708)
- Override `Cargo.lock` checksums when doing a dry-run `publish` (rust-lang/cargo#15711)
- test(rustfix): Update for nightly (rust-lang/cargo#15717)
r? ghost
Remove support for SwitchInt edge effects in backward dataflow
Those effects are untested and unused. Remove them along with the implementation of `BasicBlocks::switch_sources`.
Add target maintainer information for aarch64-unknown-linux-musl
Mentioning ``@famfo`` so that they can review the documentation. We're both very invested in this target; I originally promoted it to tier 2 with host tools in rust-lang/rust#76420 back in 2020.
Clarify and expand documentation for std::sys_common dependency structure
This PR makes a minor improvement to the module-level documentation of std::sys_common:
Replaces the lowercase “dag” with the more standard and explicit form “DAG (Directed Acyclic Graph)” for clarity.
Port several trait/coherence-related attributes the new attribute system
Part of rust-lang/rust#131229
This ports:
- `#[const_trait]`
- `#[rustc_deny_explicit_impl]`
- `#[rustc_do_not_implement_via_object]`
- `#[rustc_coinductive]`
- `#[type_const]`
- `#[rustc_specialization_trait]`
- `#[rustc_unsafe_specialization_marker]`
- `#[marker]`
- `#[fundamental]`
- `#[rustc_paren_sugar]`
- `#[rustc_allow_incoherent_impl]`
- `#[rustc_coherence_is_core]`
This also changes `#[marker]` to error on duplicates instead of warning.
cc rust-lang/rust#142838, but I don't think it matters too much, since it's unstable.
r? ``@oli-obk``
Fix a mix-up of a block with its predecessors in handling of SwitchInt
edge effects for backward analysis. Note that this functionality is
currently unused, so change has no practical impact.
Make UB transmutes really UB in LLVM
Ralf suggested in <https://github.com/rust-lang/rust/pull/143410#discussion_r2184928123> that UB transmutes shouldn't be trapping, which happened for the one path *that* PR was changing, but there's another path as well, so *this* PR changes that other path to match.
r? codegen
fix: Include frontmatter in -Zunpretty output
In the implementation (rust-lang/rust#140035), this was left as an open question for
the tracking issue (rust-lang/rust#136889). My assumption is that this should be
carried over.
The test was carried over from rust-lang/rust#137193 which was superseded by rust-lang/rust#140035.
Thankfully, either way, `-Zunpretty` is unstable and we can always
change it even if we stabilize frontmatter.
chore: Improve how the other suggestions message gets rendered
Note: This change is part of my ongoing work to use `annotate-snippets` as `rustc`'s emitter
This change started as a way to remove some specialty code paths from `annotate-snippets`, by making the "and {} other candidates" message get rendered like a secondary message with no level, but turned into a fix for the message's Unicode output. Before this change, when using the Unicode output, the other suggestions message would get rendered outside of the main suggestion block, making it feel disconnected from what it was referring to. This change makes it so that the message is on the last line of the block, aligning its rendering with other secondary messages, and making it clear what the message is referring to.
Before:
```
error[E0433]: failed to resolve: use of undeclared type `IntoIter`
╭▸ $DIR/issue-82956.rs:28:24
│
LL │ let mut iter = IntoIter::new(self);
│ ━━━━━━━━ use of undeclared type `IntoIter`
╰╴
help: consider importing one of these structs
╭╴
LL + use std::array::IntoIter;
├╴
LL + use std::collections::binary_heap::IntoIter;
├╴
LL + use std::collections::btree_map::IntoIter;
├╴
LL + use std::collections::btree_set::IntoIter;
╰╴
and 9 other candidates
```
After:
```
error[E0433]: failed to resolve: use of undeclared type `IntoIter`
╭▸ $DIR/issue-82956.rs:28:24
│
LL │ let mut iter = IntoIter::new(self);
│ ━━━━━━━━ use of undeclared type `IntoIter`
╰╴
help: consider importing one of these structs
╭╴
LL + use std::array::IntoIter;
├╴
LL + use std::collections::binary_heap::IntoIter;
├╴
LL + use std::collections::btree_map::IntoIter;
├╴
LL + use std::collections::btree_set::IntoIter;
│
╰ and 9 other candidates
```
`tests/ui`: A New Order [28/28] FINAL PART
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? ``@tgross35``
`tests/ui`: A New Order [27/N]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
Some `tests/ui/` housekeeping, to trim down number of tests directly under `tests/ui/`. Part of rust-lang/rust#133895.
r? ``@tgross35``
Properly track the depth when expanding free alias types
Decrease the depth after the fold so as not to affect the depth for unrelated same-level constituent types. My bad.
Fixesrust-lang/rust#142419.
Rework borrowing suggestions to use `Expr` instead of just `Span`
In the suggestion machinery for borrowing expressions and types, always use the available obligation `Span` to find the appropriate `Expr` to perform appropriateness checks no the `ExprKind` instead of on the textual snippet corresponding to the `Span`. (We were already doing this, but only for a subset of cases.) This now better handles situations where parentheses and `<>` are needed for correct syntax (`&(foo + bar)`, `(&foo).bar()`, `<&Foo>::bar()`, etc.).
Unify the logic for the case where `&` *and* `&mut` are appropriate with the logic for only one of those cases. (Instead of having two branches for emitting the suggestion, we now have a single one, using `Diag::multipart_suggestions` always.)
Handle the case when `S::foo()` should have been `<&S>::foo()` (instead of suggesting the prior `&S::foo()`. Fixrust-lang/rust#143393.
Make `Diag::multipart_suggestions` always verbose. CC rust-lang/rust#141973.
Resolve refactor: extraction of `finalize_module_binding` and `single_import_can_define_name`
This pr the work Vadim asked for in https://github.com/rust-lang/rust/pull/142547#issuecomment-3001339385. This part:
> finalize_module_binding/single_import_can_define_name extraction
Cherry-picked commits of b-naber. Extraction of 2 processes in `resolve_ident_in_module_unadjusted`:
- `finalize_module_binding`
- `single_import_can_define_name`
r? ```@petrochenkov```
Make some "safe" llvm ops actually sound
Noticed while doing other refactorings
it may cause some extra unnecessary allocations, but the current use sites are rare ones anyway
Fix `--skip-std-check-if-no-download-rustc`
Since https://github.com/rust-lang/rust/pull/143048, we now explicitly set the build compiler for `check::Std`, which caused it to be built before we checked `--skip-std-check-if-no-download-rustc`. So I moved the check earlier to `make_run`, which resolves it.
I also added a regression test for this. Sadly we can't really test for the positive case easily (when download-ci-rustc is enabled), but we can test the negative cases, where it is disabled.
Fixes: https://github.com/rust-lang/rust/issues/143705
r? ```@RalfJung```
Add an aarch64-msvc build running on ARM64 Windows
Resurrecting rust-lang/rust#126341
Per <https://github.com/rust-lang/rfcs/pull/3817> we intend to promote `aarch64-pc-windows-msvc` to Tier 1. As part of that work, we are adding a pre-merge CI job to validate that changes do not break this target.
Additionally, for consistency, the `dist-aarch64-msvc` job will also be run on Arm64 Windows runners.
r? ``@Kobzol``
try-job: `*aarch64-msvc*`
Rollup of 9 pull requests
Successful merges:
- rust-lang/rust#143446 (use `--dynamic-list` for exporting executable symbols)
- rust-lang/rust#143590 (Fix weird rustdoc output when single and glob reexport conflict on a name)
- rust-lang/rust#143599 (emit `.att_syntax` when global/naked asm use that option)
- rust-lang/rust#143615 (Fix handling of no_std targets in `doc::Std` step)
- rust-lang/rust#143632 (fix: correct parameter names in LLVMRustBuildMinNum and LLVMRustBuildMaxNum FFI declarations)
- rust-lang/rust#143640 (Constify `Fn*` traits)
- rust-lang/rust#143651 (Win: Use exceptions with empty data for SEH panic exception copies instead of a new panic)
- rust-lang/rust#143660 (Disable docs for `compiler-builtins` and `sysroot`)
- rust-lang/rust#143665 ([rustdoc-json] Add tests for `#[doc(hidden)]` handling of items.)
r? `@ghost`
`@rustbot` modify labels: rollup