Commit Graph

45984 Commits

Author SHA1 Message Date
Matthias Krüger
a8ebfb256a
Rollup merge of #139261 - RalfJung:msvc-align-mitigation, r=oli-obk
mitigate MSVC alignment issue on x86-32

This implements mitigation for https://github.com/rust-lang/rust/issues/112480 by stopping to emit `align` attributes on loads and function arguments when building for a win32 MSVC target. MSVC is known to not properly align `u64` and similar types, and claiming to LLVM that everything is properly aligned increases the chance that this will cause problems.

Of course, the misalignment is still a bug, but we can't fix that bug, only MSVC can.

Also add an errata note to the platform support page warning users about this known problem.

try-job: `i686-msvc*`
2025-04-24 11:40:35 +02:00
bors
7f695232a8 Auto merge of #140168 - joshlf:no-nfas, r=jswrenn
transmute: Mark edges by byte sets, not byte values

This leads to drastic performance improvements. For example, on the author's 2024 MacBook Pro, the time to convert the `Tree` representation of a `u64` to its equivalent DFA representation drops from ~8.5ms to ~1us, a reduction of ~8,500x. See `bench_dfa_from_tree`.

Similarly, the time to execute a transmutability query from `u64` to `u64` drops from ~35us to ~1.7us, a reduction of ~20x. See `bench_transmute`.

r? `@jswrenn`
2025-04-24 05:36:38 +00:00
bors
c02a4f0852 Auto merge of #139309 - RalfJung:abi_unsupported_vector_types, r=fee1-dead,traviscross
make abi_unsupported_vector_types a hard error

Fixes https://github.com/rust-lang/rust/issues/116558 by completing the transition; see that issue for context. The lint was introduced with Rust 1.84 and this has been shown in cargo's future breakage reports since Rust 1.85, released 6 weeks ago, and so far we got 0 complaints by users. There's not even a backlink on the tracking issue. We did a [crater run](https://github.com/rust-lang/rust/pull/127731#issuecomment-2286736295) when the lint was originally added and found no breakage. So I don't think we need another crater run now, but I can do one if the team prefers that.

https://github.com/rust-lang/rust/issues/131800 is done, so for most current targets (in particular, all tier 1 and tier 2 targets) we have the information to implement this check (modulo the targets where we don't properly support SIMD vectors yet, see the sub-issues of https://github.com/rust-lang/rust/issues/116558). If a new target gets added in the future, it will default to reject all SIMD vector types until proper information is added, which is the default we want.

This will need approval by for `@rust-lang/lang.` Cc `@workingjubilee` `@veluca93`

try-job: test-various
try-job: armhf-gnu
try-job: dist-i586-gnu-i586-i686-musl
2025-04-24 00:44:40 +00:00
bors
fa58ce343a Auto merge of #138845 - compiler-errors:stall-generators, r=lcnr
Properly stall coroutine witnesses in new solver

TODO: write description

r? lcnr
2025-04-23 21:35:15 +00:00
Joshua Liebow-Feeser
4326a44e6f transmutability: Mark edges by ranges, not values
In the `Tree` and `Dfa` representations of a type's layout, store byte
ranges rather than needing to separately store each byte value. This
permits us to, for example, represent a `u8` using a single 0..=255 edge
in the DFA rather than using 256 separate edges.

This leads to drastic performance improvements. For example, on the
author's 2024 MacBook Pro, the time to convert the `Tree` representation
of a `u64` to its equivalent DFA representation drops from ~8.5ms to
~1us, a reduction of ~8,500x. See `bench_dfa_from_tree`.

Similarly, the time to execute a transmutability query from `u64` to
`u64` drops from ~35us to ~1.7us, a reduction of ~20x. See
`bench_transmute`.
2025-04-23 11:45:00 -07:00
bors
553600e0f5 Auto merge of #140180 - ChrisDenton:rollup-5pvs08u, r=ChrisDenton
Rollup of 7 pull requests

Successful merges:

 - #140142 (Some more graphviz tweaks)
 - #140146 (Update `compiler_builtins` to 0.1.156)
 - #140147 (Clean: rename `open_braces` to `open_delimiters` in lexer and move `make_unclosed_delims_error` into `diagnostics.rs`.)
 - #140160 (Use `is_lang_item` and `as_lang_item` instead of handrolling their logic)
 - #140163 (Validate extension in `PathBuf::add_extension`)
 - #140173 (Ping Mara when touching format_args!() internals.)
 - #140175 (`rc""` more clear error message)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-04-23 15:12:33 +00:00
Michael Goulet
f943f73db4 More 2025-04-23 15:09:25 +00:00
Chris Denton
ecb9775438
Rollup merge of #140175 - Kivooeo:new-fix-one, r=compiler-errors
`rc""` more clear error message

here is small fix that provides better error message when user is trying to use `rc""` the same way it was made for `rb""`

example of it's work

```rust
  |
2 |     rc"\n";
  |     ^^ unknown prefix
  |
  = note: prefixed identifiers and literals are reserved since Rust 2021
help: use `cr` for a raw C-string
  |
2 -     rc"\n";
2 +     cr"\n";
  |
```

**related issue**
fixes #140170

cc `@cyrgani` (issue author)
2025-04-23 00:43:08 +00:00
Chris Denton
b03267fc11
Rollup merge of #140160 - oli-obk:lang-items, r=jieyouxu
Use `is_lang_item` and `as_lang_item` instead of handrolling their logic

Various cleanups and deduplication. Most notably `if is_lang_item(foo, bar) {} else if is_lang_item...` chains are turned into matches. No behaviour changes intended beyond turning ICEs into fatal "lang item not found" errors
2025-04-23 00:43:07 +00:00
Chris Denton
090f6a9629
Rollup merge of #140147 - xizheyin:issue-138401-1, r=compiler-errors
Clean: rename `open_braces` to `open_delimiters` in lexer and move `make_unclosed_delims_error` into `diagnostics.rs`.

Clean code prepared for resolving #138401. To avoid having too many extraneous changes in one PR, I cleaned up some of the naming and method placement in lexer in this PR.
1. For the make_unclosed_delims_error function defined in mod.rs is only used in lexer, so moved into lexer, which enhances encapsulation.
2. For open_braces in TokenTreeDiagInfo the naming is not canonical, as Brace refers to `{...} ` and this variable can store all kinds of different Delimiters. so I named it open_delimiters.

r? `@chenyukang`
2025-04-23 00:43:06 +00:00
Chris Denton
1b9e11ed3b
Rollup merge of #140142 - nnethercote:some-graphviz-tweaks-2, r=compiler-errors
Some more graphviz tweaks

A follow-up to #132346.

r? `@davidtwco`
2025-04-23 00:43:05 +00:00
Kivooeo
44b19e5fe7 rc and cr more clear error message 2025-04-23 03:15:43 +05:00
Michael Goulet
7c1661f945 Consider Copy/Clone too 2025-04-22 17:05:15 +00:00
Michael Goulet
1727badf77 Don't compute query unless in new solver 2025-04-22 17:04:59 +00:00
Michael Goulet
a922983393 Eagerly instantiate coroutine witness in new solver 2025-04-22 16:50:38 +00:00
Michael Goulet
169955f3be Properly drain pending obligations for coroutines 2025-04-22 16:50:38 +00:00
Michael Goulet
67df5b9cfa Collect and resolve ambiguous obligations from normalizing in writeback 2025-04-22 16:50:38 +00:00
Chris Denton
15f8847a25
Rollup merge of #140144 - nnethercote:fix-140098, r=petrochenkov
Handle another negated literal in `eat_token_lit`.

Extends the change from #139653, which was on expressions, to literals.

Fixes #140098.

r? ``@petrochenkov``
2025-04-22 15:24:08 +00:00
Chris Denton
264249fbe1
Rollup merge of #140104 - Shourya742:2025-04-21-auto-diff-fails-on-impl-block, r=ZuseZ4
Fix auto diff failing on inherent impl blocks

closes: #139557

r? ``@ZuseZ4``
2025-04-22 15:24:07 +00:00
Chris Denton
107f04daa8
Rollup merge of #140072 - folkertdev:miri-fn-align, r=RalfJung
handle function alignment in miri

tracking issue: https://github.com/rust-lang/rust/issues/82232
Fixes https://github.com/rust-lang/miri/issues/4282

The `#[repr(align(N))]` attribute on functions was ignored when using miri. For such a function, its address should be a multiple of `N`.

There is some further discussion in the thread [#t-compiler/const-eval > function address alignment](https://rust-lang.zulipchat.com/#narrow/channel/146212-t-compiler.2Fconst-eval/topic/function.20address.20alignment) on how `dyn Fn` should be handled. The behavior there appears to be consistent between miri and nightly, though both may be incorrect. In any case, that can be resolved separately.
2025-04-22 15:24:06 +00:00
Chris Denton
8089e317b5
Rollup merge of #139921 - Kivooeo:master, r=WaffleLapkin
improve diagnostic for raw pointer field access with ->

This PR enhances the error messages emitted by the Rust compiler when users attempt to use the `->` operator for field access on raw pointers or when dereferencing is needed. The changes aim to provide clearer guidance, by suggesting the correct use of the `.` operator and explicit dereferencing.

**Before:**
```
help: `xs` is a raw pointer; try dereferencing it
   |
LL |         (*xs)->count += 1;
   |         ++  +
```

**Now:**
```
help: use `.` on a dereferenced raw pointer instead
   |
LL -         xs->count += 1;
LL +         (*xs).count += 1;
   |
```

I added extra clarification in the message. Since this error occurs in the parser, we can't be certain that the type is a raw pointer. That's why the message includes only a small note in brackets. (In contrast, the message above is emitted in HIR, where we *can* check whether it's a raw pointer.)

**Before:**
```
  --> main.rs:11:11
   |
11 |         xs->count += 1;
   |           ^^
   |
   = help: the . operator will dereference the value if needed
```
**After:**
```
--> main.rs:11:11
   |
11 |         xs->count += 1;
   |           ^^
   |
   = help: the `.` operator will automatically dereference the value, except if the value is a raw pointer
```
2025-04-22 15:24:05 +00:00
Oli Scherer
5d2952100f Use is_lang_item and as_lang_item instead of handrolling their logic 2025-04-22 11:02:37 +00:00
Ralf Jung
47a1278841
add comment for "Other" case 2025-04-22 11:40:48 +02:00
bors
8bf5a8d12f Auto merge of #132833 - est31:stabilize_let_chains, r=fee1-dead
Stabilize let chains in the 2024 edition

# Stabilization report

This proposes the stabilization of `let_chains` ([tracking issue], [RFC 2497]) in the [2024 edition] of Rust.

[tracking issue]: https://github.com/rust-lang/rust/issues/53667
[RFC 2497]: https://github.com/rust-lang/rfcs/pull/2497
[2024 edition]: https://doc.rust-lang.org/nightly/edition-guide/rust-2024/index.html

## What is being stabilized

The ability to `&&`-chain `let` statements inside `if` and `while` is being stabilized, allowing intermixture with boolean expressions. The patterns inside the `let` sub-expressions can be irrefutable or refutable.

```Rust
struct FnCall<'a> {
    fn_name: &'a str,
    args: Vec<i32>,
}

fn is_legal_ident(s: &str) -> bool {
    s.chars()
        .all(|c| ('a'..='z').contains(&c) || ('A'..='Z').contains(&c))
}

impl<'a> FnCall<'a> {
    fn parse(s: &'a str) -> Option<Self> {
        if let Some((fn_name, after_name)) = s.split_once("(")
            && !fn_name.is_empty()
            && is_legal_ident(fn_name)
            && let Some((args_str, "")) = after_name.rsplit_once(")")
        {
            let args = args_str
                .split(',')
                .map(|arg| arg.parse())
                .collect::<Result<Vec<_>, _>>();
            args.ok().map(|args| FnCall { fn_name, args })
        } else {
            None
        }
    }
    fn exec(&self) -> Option<i32> {
        let iter = self.args.iter().copied();
        match self.fn_name {
            "sum" => Some(iter.sum()),
            "max" => iter.max(),
            "min" => iter.min(),
            _ => None,
        }
    }
}

fn main() {
    println!("{:?}", FnCall::parse("sum(1,2,3)").unwrap().exec());
    println!("{:?}", FnCall::parse("max(4,5)").unwrap().exec());
}
```

The feature will only be stabilized for the 2024 edition and future editions. Users of past editions will get an error with a hint to update the edition.

closes #53667

## Why 2024 edition?

Rust generally tries to ship new features to all editions. So even the oldest editions receive the newest features. However, sometimes a feature requires a breaking change so much that offering the feature without the breaking change makes no sense. This occurs rarely, but has happened in the 2018 edition already with `async` and `await` syntax. It required an edition boundary in order for `async`/`await` to become keywords, and the entire feature foots on those keywords.

In the instance of let chains, the issue is the drop order of `if let` chains. If we want `if let` chains to be compatible with `if let`, drop order makes it hard for us to [generate correct MIR]. It would be strange to have different behaviour for `if let ... {}` and `if true && let ... {}`. So it's better to [stay consistent with `if let`].

In edition 2024, [drop order changes] have been introduced to make `if let` temporaries be lived more shortly. These changes also affected `if let` chains. These changes make sense even if you don't take the `if let` chains MIR generation problem into account. But if we want to use them as the solution to the MIR generation problem, we need to restrict let chains to edition 2024 and beyond: for let chains, it's not just a change towards more sensible behaviour, but one required for correct function.

[generate correct MIR]: https://github.com/rust-lang/rust/issues/104843
[stay consistent with `if let`]: https://github.com/rust-lang/rust/pull/103293#issuecomment-1293408574
[drop order changes]: https://github.com/rust-lang/rust/issues/124085

## Introduction considerations

As edition 2024 is very new, this stabilization PR only makes it possible to use let chains on 2024 without that feature gate, it doesn't mark that feature gate as stable/removed. I would propose to continue offering the `let_chains` feature (behind a feature gate) for a limited time (maybe 3 months after stabilization?) on older editions to allow nightly users to adopt edition 2024 at their own pace. After that, the feature gate shall be marked as *stabilized*, not removed, and replaced by an error on editions 2021 and below.

## Implementation history

* History from before March 14, 2022 can be found in the [original stabilization PR] that was reverted.
* https://github.com/rust-lang/rust/pull/94927
* https://github.com/rust-lang/rust/pull/94951
* https://github.com/rust-lang/rust/pull/94974
* https://github.com/rust-lang/rust/pull/95008
* https://github.com/rust-lang/rust/pull/97295
* https://github.com/rust-lang/rust/pull/98633
* https://github.com/rust-lang/rust/pull/99731
* https://github.com/rust-lang/rust/pull/102394
* https://github.com/rust-lang/rust/pull/100526
* https://github.com/rust-lang/rust/pull/100538
* https://github.com/rust-lang/rust/pull/102998
* https://github.com/rust-lang/rust/pull/103405
* https://github.com/rust-lang/rust/pull/103293
* https://github.com/rust-lang/rust/pull/107251
* https://github.com/rust-lang/rust/pull/110568
* https://github.com/rust-lang/rust/pull/115677
* https://github.com/rust-lang/rust/pull/117743
* https://github.com/rust-lang/rust/pull/117770
* https://github.com/rust-lang/rust/pull/118191
* https://github.com/rust-lang/rust/pull/119554
* https://github.com/rust-lang/rust/pull/129394
* https://github.com/rust-lang/rust/pull/132828
* https://github.com/rust-lang/reference/pull/1179
* https://github.com/rust-lang/reference/pull/1251
* https://github.com/rust-lang/rustfmt/pull/5910

[original stabilization PR]: https://github.com/rust-lang/rust/pull/94927

## Adoption history

### In the compiler

* History before March 14, 2022 can be found in the [original stabilization PR].
* https://github.com/rust-lang/rust/pull/115983
* https://github.com/rust-lang/rust/pull/116549
* https://github.com/rust-lang/rust/pull/116688

### Outside of the compiler

* https://github.com/rust-lang/rust-clippy/pull/11750
* [rspack](https://github.com/web-infra-dev/rspack)
* [risingwave](https://github.com/risingwavelabs/risingwave)
* [dylint](https://github.com/trailofbits/dylint)
* [convex-backend](https://github.com/get-convex/convex-backend)
* [tikv](https://github.com/tikv/tikv)
* [Daft](https://github.com/Eventual-Inc/Daft)
* [greptimedb](https://github.com/GreptimeTeam/greptimedb)

## Tests

<details>

### Intentional restrictions

[`partially-macro-expanded.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/partially-macro-expanded.rs), [`macro-expanded.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs): it is possible to use macros to expand to both the pattern and the expression inside a let chain, but not to the entire `let pat = expr` operand.
[`parens.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs): `if (let pat = expr)` is not allowed in chains
[`ensure-that-let-else-does-not-interact-with-let-chains.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs): `let...else` doesn't support chaining.

### Overlap with match guards

[`move-guard-if-let-chain.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs): test for the `use moved value` error working well in match guards. could maybe be extended with let chains that have more than one `let`
[`shadowing.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs): shadowing in if let guards works as expected
[`ast-validate-guards.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs): let chains in match guards require the match guards feature gate

### Simple cases from the early days

PR #88642 has added some tests with very simple usages of `let else`, mostly as regression tests to early bugs.

[`then-else-blocks.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/then-else-blocks.rs)
[`ast-lowering-does-not-wrap-let-chains.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/ast-lowering-does-not-wrap-let-chains.rs)
[`issue-90722.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/issue-90722.rs)
[`issue-92145.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/issue-92145.rs)

### Drop order/MIR scoping tests

[`issue-100276.rs`](4adafcf40a/tests/ui/drop/issue-100276.rs): let expressions on RHS aren't terminating scopes
[`drop_order.rs`](4adafcf40a/tests/ui/drop/drop_order.rs): exhaustive temporary drop order test for various Rust constructs, including let chains
[`scope.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/scope.rs): match guard scoping test
[`drop-scope.rs`](4adafcf40a/tests/ui/rfcs/rfc-2294-if-let-guard/drop-scope.rs): another match guard scoping test, ensuring that temporaries in if-let guards live for the arm
[`drop_order_if_let_rescope.rs`](4adafcf40a/tests/ui/drop/drop_order_if_let_rescope.rs): if let rescoping on edition 2024, including chains
[`mir_let_chains_drop_order.rs`](4adafcf40a/tests/ui/mir/mir_let_chains_drop_order.rs): comprehensive drop order test for let chains, distinguishes editions 2021 and 2024.
[`issue-99938.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/issue-99938.rs), [`issue-99852.rs`](4adafcf40a/tests/ui/mir/issue-99852.rs) both bad MIR ICEs fixed by #102394

### Linting

[`irrefutable-lets.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/irrefutable-lets.rs): trailing and leading irrefutable let patterns get linted for, others don't. The lint is turned off for `else if`.
[`issue-121070-let-range.rs`](4adafcf40a/tests/ui/lint/issue-121070-let-range.rs): regression test for false positive of the unused parens lint, precedence requires the `()`s here

### Parser: intentional restrictions

[`disallowed-positions.rs`](2128d8df0e/tests/ui/rfcs/rfc-2497-if-let-chains/disallowed-positions.rs): `let` in expression context is rejected everywhere except at the top level
[`invalid-let-in-a-valid-let-context.rs`](4adafcf40a/tests/ui/rfcs/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs): nested `let` is not allowed (let's are no legal expressions just because they are allowed in `if` and `while`).

### Parser: recovery

[`issue-103381.rs`](4adafcf40a/tests/ui/parser/issues/issue-103381.rs): Graceful recovery of incorrect chaining of `if` and `if let`
[`semi-in-let-chain.rs`](4adafcf40a/tests/ui/parser/semi-in-let-chain.rs): Ensure that stray `;`s in let chains give nice errors (`if_chain!` users might be accustomed to `;`s)
[`deli-ident-issue-1.rs`](4adafcf40a/tests/ui/parser/deli-ident-issue-1.rs), [`brace-in-let-chain.rs`](4adafcf40a/tests/ui/parser/brace-in-let-chain.rs): Ensure that stray unclosed `{`s in let chains give nice errors and hints

### Misc

[`conflicting_bindings.rs`](4adafcf40a/tests/ui/pattern/usefulness/conflicting_bindings.rs): the conflicting bindings check also works in let chains. Personally, I'd extend it to chains with multiple let's as well.
[`let-chains-attr.rs`](4adafcf40a/tests/ui/expr/if/attrs/let-chains-attr.rs): attributes work on let chains

### Tangential tests with `#![feature(let_chains)]`

[`if-let.rs`](4adafcf40a/tests/coverage/branch/if-let.rs): MC/DC coverage tests for let chains
[`logical_or_in_conditional.rs`](4adafcf40a/tests/mir-opt/building/logical_or_in_conditional.rs): not really about let chains, more about dropping/scoping behaviour of `||`
[`stringify.rs`](4adafcf40a/tests/ui/macros/stringify.rs): exhaustive test of the `stringify` macro
[`expanded-interpolation.rs`](4adafcf40a/tests/ui/unpretty/expanded-interpolation.rs), [`expanded-exhaustive.rs`](4adafcf40a/tests/ui/unpretty/expanded-exhaustive.rs): Exhaustive test of `-Zunpretty`
[`diverges-not.rs`](4adafcf40a/tests/ui/rfcs/rfc-0000-never_patterns/diverges-not.rs): Never type, mostly tangential to let chains

</details>

## Possible future work

* There is proposals to allow `if let Pat(bindings) = expr {}` to be written as `if expr is Pat(bindings) {}` ([RFC 3573]). `if let` chains are a natural extension of the already existing `if let` syntax, and I'd argue orthogonal towards `is` syntax.
  * https://github.com/rust-lang/lang-team/issues/297
* One could have similar chaining inside `let ... else` statements. There is no proposed RFC for this however, nor is it implemented on nightly.
* Match guards have the `if` keyword as well, but on stable Rust, they don't support `let`. The functionality is available via an unstable feature ([`if_let_guard` tracking issue]). Stabilization of let chains affects this feature in so far as match guards containing let chains now only need the `if_let_guard` feature gate be present instead of also the `let_chains` feature (NOTE: this PR doesn't implement this simplification, it's left for future work).

[RFC 3573]: https://github.com/rust-lang/rfcs/pull/3573
[`if_let_guard` tracking issue]: https://github.com/rust-lang/rust/issues/51114

## Open questions / blockers

- [ ] bad recovery if you don't put a `let` (I don't think this is a blocker): [#117977](https://github.com/rust-lang/rust/issues/117977)
- [x] An instance where a temporary lives shorter than with nested ifs, breaking compilation: [#103476](https://github.com/rust-lang/rust/issues/103476). Personally I don't think this is a blocker either, as it's an edge case. Edit: turns out to not reproduce in edition 2025 any more, due to let rescoping. regression test added in #133093
- [x] One should probably extend the tests for `move-guard-if-let-chain.rs` and `conflicting_bindings.rs` to have chains with multiple let's: done in 133093
- [x] Parsing rejection tests: addressed by https://github.com/rust-lang/rust/pull/132828
- [x] [Style](https://rust-lang.zulipchat.com/#narrow/channel/346005-t-style/topic/let.20chains.20stabilization.20and.20formatting): https://github.com/rust-lang/rust/pull/139456
- [x] https://github.com/rust-lang/rust/issues/86730 explicitly mentions `let_else`. I think we can live with `let pat = expr` not evaluating as `expr` for macro_rules macros, especially given that `let pat = expr` is not a legal expression anywhere except inside `if` and `while`.
- [x] Documentation in the reference: https://github.com/rust-lang/reference/pull/1740
- [x] Add chapter to the Rust 2024 [edition guide]: https://github.com/rust-lang/edition-guide/pull/337
- [x] Resolve open questions on desired drop order.

[original reference PR]: https://github.com/rust-lang/reference/pull/1179
[edition guide]: https://github.com/rust-lang/edition-guide
2025-04-22 07:54:10 +00:00
xizheyin
dce5d99ce8 Rename open_brace to open_delimiters
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
2025-04-22 14:37:26 +08:00
xizheyin
e827b17ddb Move make_unclosed_delims_error to lexer/diagonostics.rs
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
2025-04-22 14:37:26 +08:00
Nicholas Nethercote
6be270be0c Handle another negated literal in eat_token_lit.
Extends the change from #139653, which was on expressions, to literals.

Fixes #140098.
2025-04-22 15:08:32 +10:00
bors
9bfa31f632 Auto merge of #140138 - ChrisDenton:rollup-zw7jibi, r=ChrisDenton
Rollup of 5 pull requests

Successful merges:

 - #139981 (Don't compute name of associated item if it's an RPITIT)
 - #140077 (Construct OutputType using macro and print [=FILENAME] help info)
 - #140081 (Update `libc` to 0.2.172)
 - #140094 (Improve diagnostics for pointer arithmetic += and -= (fixes #137391))
 - #140128 (Use correct annotation for CSS pseudo elements)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-04-22 04:44:13 +00:00
Chris Denton
8f42ac0043
Rollup merge of #140094 - Kivooeo:raw-pointer-assignment-suggestion, r=compiler-errors
Improve diagnostics for pointer arithmetic += and -= (fixes #137391)

**Description**:

This PR improves the diagnostic message for cases where a binary assignment operation like `ptr += offset` or `ptr -= offset` is attempted on `*mut T`. These operations are not allowed, and the compiler previously suggested calling `.add()` or `.wrapping_add()`, which is misleading if not assigned.

This PR updates the diagnostics to suggest assigning the result of `.wrapping_add()` or `.wrapping_sub()` back to the pointer, e.g.:

**Examples**

For this code
```rust
let mut arr = [0u8; 10];
let mut ptr = arr.as_mut_ptr();

ptr += 2;
```
it will say:
```rust
10 |     ptr += 2;
   |     ---^^^^^
   |     |
   |     cannot use `+=` on type `*mut u8`
   |
help: consider replacing `ptr += offset` with `ptr = ptr.wrapping_add(offset)` or `ptr.add(offset)`
   |
10 -     ptr += 2;
10 +     ptr = ptr.wrapping_add(2);
```

**Related issue**: #137391
cc `@nabijaczleweli` for context (issue author)
2025-04-22 01:22:13 +00:00
Chris Denton
2fff8257ad
Rollup merge of #140077 - xizheyin:issue-139805, r=jieyouxu
Construct OutputType using macro and print [=FILENAME] help info

Closes #139805

Use define_output_types to define variants of OutputType, as well as refactor all of its methods for clarity. This way no variant is missed when pattern matching or output help messages.

On top of that, I optimized for `emit` help messages.

r? ```@jieyouxu```
2025-04-22 01:22:12 +00:00
Chris Denton
32862fba47
Rollup merge of #139981 - compiler-errors:name-2, r=nnethercote
Don't compute name of associated item if it's an RPITIT

Another simple fix for an RPITIT name ICE.

Fixes https://github.com/rust-lang/rust/issues/139941
Fixes #140084

r? nnethercote
2025-04-22 01:22:11 +00:00
bors
fae7785b60 Auto merge of #139897 - nnethercote:rm-OpenDelim-CloseDelim, r=petrochenkov
Remove `token::{Open,Close}Delim`

By replacing them with `{Open,Close}{Param,Brace,Bracket,Invisible}`.

PR #137902 made `ast::TokenKind` more like `lexer::TokenKind` by
replacing the compound `BinOp{,Eq}(BinOpToken)` variants with fieldless
variants `Plus`, `Minus`, `Star`, etc. This commit does a similar thing
with delimiters. It also makes `ast::TokenKind` more similar to
`parser::TokenType`.

This requires a few new methods:
- `TokenKind::is_{,open_,close_}delim()` replace various kinds of
  pattern matches.
- `Delimiter::as_{open,close}_token_kind` are used to convert
  `Delimiter` values to `TokenKind`.

Despite these additions, it's a net reduction in lines of code. This is
because e.g. `token::OpenParen` is so much shorter than
`token::OpenDelim(Delimiter::Parenthesis)` that many multi-line forms
reduce to single line forms. And many places where the number of lines
doesn't change are still easier to read, just because the names are
shorter, e.g.:
```
-   } else if self.token != token::CloseDelim(Delimiter::Brace) {
+   } else if self.token != token::CloseBrace {
```

r? `@petrochenkov`
2025-04-22 01:15:06 +00:00
Nicholas Nethercote
521b379705 Remove unnecessary lifetime on ResultsVisitor. 2025-04-22 10:08:05 +10:00
Nicholas Nethercote
3bd1e1484f Remove unused ResultsCursor methods. 2025-04-22 09:46:24 +10:00
Nicholas Nethercote
55a80cc132 Move StateDiffCollector's use point.
Currently the graphviz code does a `results.visit_with` call while also
holding a `ResultsCursor` on the `results`. That is both kinds of
results traversals at the same time, which is awkward. This commit moves
the `results.visit_with` part earlier so the two results traversals
don't overlap.
2025-04-22 09:45:44 +10:00
Kivooeo
b5e8f1f0ce improve diagnostic for raw pointer field access using -> 2025-04-22 00:53:12 +05:00
bors
d6c1e454aa Auto merge of #140127 - ChrisDenton:rollup-2kye32h, r=ChrisDenton
Rollup of 11 pull requests

Successful merges:

 - #134213 (Stabilize `naked_functions`)
 - #139711 (Hermit: Unify `std::env::args` with Unix)
 - #139795 (Clarify why SGX code specifies linkage/symbol names for certain statics)
 - #140036 (Advent of `tests/ui` (misc cleanups and improvements) [4/N])
 - #140047 (remove a couple clones)
 - #140052 (Fix error when an intra doc link is trying to resolve an empty associated item)
 - #140074 (rustdoc-json: Improve test for auto-trait impls)
 - #140076 (jsondocck: Require command is at start of line)
 - #140107 (rustc-dev-guide subtree update)
 - #140111 (cleanup redundant pattern instances)
 - #140118 ({B,C}Str: minor cleanup)

r? `@ghost`
`@rustbot` modify labels: rollup
2025-04-21 19:28:16 +00:00
Chris Denton
8ecaf148e7
Rollup merge of #140111 - jogru0:redundant_pattern, r=compiler-errors
cleanup redundant pattern instances

Just two small code cleanups.
2025-04-21 18:53:20 +00:00
Chris Denton
96ac7d8b5e
Rollup merge of #140052 - GuillaumeGomez:fix-140026, r=nnethercote
Fix error when an intra doc link is trying to resolve an empty associated item

Fixes https://github.com/rust-lang/rust/issues/140026.

Assigning ```@nnethercote``` since they're the one who wrote the initial change.

I updated rustdoc code instead of compiler's because I think it makes more sense that the caller ensures on their side that the name they're looking for isn't empty.

r? ```@nnethercote```
2025-04-21 18:53:18 +00:00
Chris Denton
b3a0104ddb
Rollup merge of #140047 - matthiaskrgr:clo, r=compiler-errors
remove a couple clones
2025-04-21 18:53:17 +00:00
Chris Denton
1ca5e4f1c1
Rollup merge of #134213 - folkertdev:stabilize-naked-functions, r=tgross35,Amanieu,traviscross
Stabilize `naked_functions`

tracking issue: https://github.com/rust-lang/rust/issues/90957
request for stabilization on tracking issue: https://github.com/rust-lang/rust/issues/90957#issuecomment-2539270352
reference PR: https://github.com/rust-lang/reference/pull/1689

# Request for Stabilization

Two years later, we're ready to try this again. Even though this issue is already marked as having passed FCP, given the amount of time that has passed and the changes in implementation strategy, we should follow the process again.

## Summary

The `naked_functions` feature has two main parts: the `#[naked]` function attribute, and the `naked_asm!` macro.

An example of a naked function:

```rust
const THREE: usize = 3;

#[naked]
pub extern "sysv64" fn add_n(number: usize) -> usize {
    // SAFETY: the validity of the used registers
    // is guaranteed according to the "sysv64" ABI
    unsafe {
        core::arch::naked_asm!(
            "add rdi, {}",
            "mov rax, rdi",
            "ret",
            const THREE,
        )
    }
}
```

When the `#[naked]` attribute is applied to a function, the compiler won't emit a [function prologue](https://en.wikipedia.org/wiki/Function_prologue_and_epilogue) or epilogue when generating code for this function. This attribute is analogous to [`__attribute__((naked))`](https://developer.arm.com/documentation/100067/0608/Compiler-specific-Function--Variable--and-Type-Attributes/--attribute----naked---function-attribute) in C. The use of this feature allows the programmer to have precise control over the assembly that is generated for a given function.

The body of a naked function must consist of a single `naked_asm!` invocation, a heavily restricted variant of the `asm!` macro: the only legal operands are `const` and `sym`, and the only legal options are `raw` and `att_syntax`. In lieu of specifying operands, the `naked_asm!` within a naked function relies on the function's calling convention to determine the validity of registers.

## Documentation

The Rust Reference: https://github.com/rust-lang/reference/pull/1689
(Previous PR: https://github.com/rust-lang/reference/pull/1153)

## Tests

* [tests/run-make/naked-symbol-visiblity](https://github.com/rust-lang/rust/tree/master/tests/codegen/naked-fn) verifies that `pub`, `#[no_mangle]` and `#[linkage = "..."]` work correctly for naked functions
* [tests/codegen/naked-fn](https://github.com/rust-lang/rust/tree/master/tests/codegen/naked-fn) has tests for function alignment, use of generics, and validates the exact assembly output on linux, macos, windows and thumb
* [tests/ui/asm/naked-*](https://github.com/rust-lang/rust/tree/master/tests/ui/asm) tests for incompatible attributes, generating errors around incorrect use of `naked_asm!`, etc

## Interaction with other (unstable) features

### [fn_align](https://github.com/rust-lang/rust/issues/82232)

Combining `#[naked]` with `#[repr(align(N))]` works well, and is tested e.g. here

- https://github.com/rust-lang/rust/blob/master/tests/codegen/naked-fn/aligned.rs
- https://github.com/rust-lang/rust/blob/master/tests/codegen/naked-fn/min-function-alignment.rs

It's tested extensively because we do need to explicitly support the `repr(align)` attribute (and make sure we e.g. don't mistake powers of two for number of bytes).

## History

This feature was originally proposed in [RFC 1201](https://github.com/rust-lang/rfcs/pull/1201), filed on 2015-07-10 and accepted on 2016-03-21. Support for this feature was added in [#32410](https://github.com/rust-lang/rust/pull/32410), landing on 2016-03-23. Development languished for several years as it was realized that the semantics given in RFC 1201 were insufficiently specific. To address this, a minimal subset of naked functions was specified by [RFC 2972](https://github.com/rust-lang/rfcs/pull/2972), filed on 2020-08-07 and accepted on 2021-11-16. Prior to the acceptance of RFC 2972, all of the stricter behavior specified by RFC 2972 was implemented as a series of warn-by-default lints that would trigger on existing uses of the `naked` attribute; these lints became hard errors in [#93153](https://github.com/rust-lang/rust/pull/93153) on 2022-01-22. As a result, today RFC 2972 has completely superseded RFC 1201 in describing the semantics of the `naked` attribute.

More recently, the `naked_asm!` macro was added to replace the earlier use of a heavily restricted `asm!` invocation. The `naked_asm!` name is clearer in error messages, and provides a place for documenting the specific requirements of inline assembly in naked functions.

The implementation strategy was changed to emitting a global assembly block. In effect, an extern function

```rust
extern "C" fn foo() {
    core::arch::naked_asm!("ret")
}
```

is emitted as something similar to

```rust
core::arch::global_asm!(
    "foo:",
    "ret"
);

extern "C" {
    fn foo();
}
```

The codegen approach was chosen over the llvm naked function attribute because:

- the rust compiler can guarantee the behavior (no sneaky additional instructions, no inlining, etc.)
- behavior is the same on all backends (llvm, cranelift, gcc, etc)

Finally, there is now an allow list of compatible attributes on naked functions, so that e.g. `#[inline]` is rejected with an error. The `#[target_feature]` attribute on naked functions was later made separately unstable, because implementing it is complex and we did not want to block naked functions themselves on how target features work on them. See also https://github.com/rust-lang/rust/issues/138568.

relevant PRs for these recent changes

- https://github.com/rust-lang/rust/pull/127853
- https://github.com/rust-lang/rust/pull/128651
- https://github.com/rust-lang/rust/pull/128004
- https://github.com/rust-lang/rust/pull/138570
-
### Various historical notes

#### `noreturn`
[RFC 2972](https://github.com/rust-lang/rfcs/blob/master/text/2972-constrained-naked.md) mentions that naked functions

> must have a body which contains only a single asm!() statement which:
> iii. must contain the noreturn option.

Instead of `asm!`, the current implementation mandates that the body contain a single `naked_asm!` statement. The `naked_asm!` macro is a heavily restricted version of the `asm!` macro, making it easier to talk about and document the rules of assembly in naked functions and give dedicated error messages.

For `naked_asm!`, the behavior of the `asm!`'s `noreturn` option is implicit. The `noreturn` option means that it is UB for control flow to fall through the end of the assembly block. With `asm!`, this option is usually used for blocks that diverge (and thus have no return and can be typed as `!`). With `naked_asm!`, the intent is different: usually naked funtions do return, but they must do so from within the assembly block. The `noreturn` option was used so that the compiler would not itself also insert a `ret` instruction at the very end.

#### padding / `ud2`

A `naked_asm!` block that violates the safety assumption that control flow must not fall through the end of the assembly block is UB. Because no return instruction is emitted, whatever bytes follow the naked function will be executed, resulting in truly undefined behavior. There has been discussion whether rustc should emit an invalid instruction (e.g. `ud2`  on x86) after the `naked_asm!` block to at least fail early in the case of an invalid `naked_asm!`. It was however decided that it is more useful to guarantee that `#[naked]` functions NEVER contain any instructions besides those in the `naked_asm!` block.

# unresolved questions

None

r? ``@Amanieu``

I've validated the tests on x86_64 and aarch64
2025-04-21 18:53:15 +00:00
Kivooeo
834e476a0c Add diagnostics and suggestions for raw pointer arithmetic assignments 2025-04-21 22:14:44 +05:00
Chris Denton
77325f5200
Rollup merge of #140121 - blyxyas:code_stats_pub_docs, r=jieyouxu
Document why CodeStats::type_sizes is public

As indicated in [this comment](https://github.com/rust-lang/rust/pull/139876#issuecomment-2808932673) from #139876
> Need some comment, otherwise this pub can be eventually removed as unused.

r? `@nnethercote`
2025-04-21 15:56:00 +00:00
Chris Denton
c43b82f576
Rollup merge of #140030 - EnzymeAD:autodiff-debug, r=jieyouxu
Fix autodiff debug builds

r? `@oli-obk`

closes: #139704

Tracking:

- https://github.com/rust-lang/rust/issues/124509
2025-04-21 15:55:59 +00:00
Chris Denton
f79eef91df
Rollup merge of #140021 - compiler-errors:no-deep-norm-ice, r=lcnr
Don't ICE on pending obligations from deep normalization in a loop

See the comment I left inline in `compiler/rustc_trait_selection/src/traits/normalize.rs`.

Fixes https://github.com/rust-lang/rust/issues/133868

r? lcnr
2025-04-21 15:55:58 +00:00
blyxyas
619ed1540a Document why CodeStats::type_sizes is public 2025-04-21 17:36:36 +02:00
Jonathan Gruner
2039b36f90 cleanup redundant pattern instances 2025-04-21 14:15:32 +02:00
xizheyin
6fe881c788
Construct OutputType using macro and print [=FILENAME] help info
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
2025-04-21 18:07:58 +08:00
bit-aloo
c0c6d4280c
support both trait and non-trail associated declaration 2025-04-21 13:28:53 +05:30
Nicholas Nethercote
85f6025f45 Store Results in Formatter.
Instead of `ResultsCursor`.

This partly undoes the second commit from #132346; possible because
`Results::as_result_cursor` (which doesn't consume the `Results`) is now
available. Delaying the `ResultsCursor` construction will facilitate the
next couple of commits.
2025-04-21 10:32:19 +10:00