Commit Graph

2362 Commits

Author SHA1 Message Date
Jonathan Brouwer 82017d9f5c Rollup merge of #153736 - cyrgani:incomplete-2, r=fmease
add test that an incomplete feature emits a warning

Related to https://github.com/rust-lang/compiler-team/issues/974, this PR adds a new test to specifically check that a dummy incomplete feature triggers the `incomplete_features` lint. (since this seemed to be the favored approach on Zulip)

Alternative to https://github.com/rust-lang/rust/pull/153706.

r? fmease
2026-03-12 12:31:42 +01:00
cyrgani c909ae5a35 add test that an incomplete feature emits a warning 2026-03-11 18:26:49 +00:00
Jonathan Brouwer 2263a8e19e Rollup merge of #153072 - ferrocene:jyn/libcore-doctest-merge, r=jdonszelmann
Allow merging all libcore/alloc doctests into a single binary

This is only the changes needed to *allow* merging the tests. This doesn't actually turn doctest merging on in bootstrap. I think that might be a useful follow-up, since it makes them much faster to run, but it's not without downsides because it means we'll no longer be testing that doctests have all necessary `feature()` attributes.

The motivation for this change is to run the tests with `-C instrument-coverage` and then generate a coverage report from the output. Currently, this is very expensive because it requires parsing DWARF for each doctest binary. Merging the binaries decreases the time taken from several hours to ~30 seconds.

---

There are several parts to this change, most of which are independent and I'm happy to split out into other PRs.

- Upgrade process spawning logging from debug->info so it's easier to see, including in a rustdoc built without debug symbols.
- Core doctests now support being run with `-C panic=abort`. Ferrocene needs this downstream for complicated reasons; it's a one-line change so I figured it's not a big deal.
- Downgrade errors about duplicate features from a hard error to a warning. The meaning is clear here, and doctest merging often creates duplicate features since it lifts them all to the crate root. This involves changes to the compiler but generally I expect this to be low-impact.
  - Enable this new warning, as well as several related feature lints, in rustdoc. By default rustdoc doesn't lint on anything except the lints it manually adds.
- Rustdoc now treats `allow(incomplete_features)` as a crate-level attribute, just like `internal_features`. Without this, it's possible to get hard errors if rustdoc lifts features to the crate level but not `allow`s.
- Core doctests now support being built with `--merge-doctests=yes`. In particular, I removed a few `$crate` usages and explicitly marked a few doctests as `standalone_crate`.
2026-03-11 10:58:50 +01:00
Nicholas Nethercote c12ab08c14 Move Spanned.
It's defined in `rustc_span::source_map` which doesn't make any sense
because it has nothing to do with source maps. This commit moves it to
the crate root, a more sensible spot for something this basic.
2026-03-11 06:25:23 +11:00
Jynn Nelson efe2e6c6c6 rustdoc moves incomplete_features attr up to the top level 2026-03-10 11:56:29 +01:00
Josh Stone 32bae1353e Update cfg(bootstrap) 2026-03-07 10:42:02 -08:00
Jonathan Brouwer 783c9d3de0 Rollup merge of #149937 - jyn514:linker-info, r=mati865
spliit out `linker-info` from `linker-messages`

*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/149937)*

Helps with https://github.com/rust-lang/rust/issues/136096.
2026-03-07 01:42:35 +01:00
Jynn Nelson 20404bf4a6 Split out linker-info from linker-messages
- Hide common linker output behind `linker-info`
- Add tests
- Account for different capitalization on windows-gnu when removing
  "warning" prefix
- Add some more comments
- Add macOS deployment-target test
- Ignore linker warnings from trying to statically link glibc

  I don't know what's going on in `nofile-limit.rs` but I want no part
  of it.

- Use a fake linker so tests are platform-independent
2026-03-06 10:38:21 +01:00
bors 64b72a1fa5 Auto merge of #150447 - WaffleLapkin:maybe-dangling-semantics, r=RalfJung
Implement `MaybeDangling` compiler support



Tracking issue: https://github.com/rust-lang/rust/issues/118166



cc @RalfJung
2026-03-05 12:21:27 +00:00
Jonathan Brouwer 23e27344e9 Rollup merge of #153300 - fmease:test-attrs-tweaks, r=JonathanBrouwer
Tweak some of our internal `#[rustc_*]` TEST attributes

I think I might be the one who's used the internal TEST attrs `#[rustc_{dump_predicates,object_lifetime_default,outlives,variance}]` the most in recent times, I might even be the only one. As such I've noticed some recent-ish issues that haven't been fixed so far and which keep bothering me. Moreover I have a longstanding urge to rename several of these attributes which I couldn't contain anymore.

[`#[rustc_*]` TEST attributes](https://rustc-dev-guide.rust-lang.org/compiler-debugging.html#rustc_-test-attributes) are internal attributes that basically allow you to dump the output of specific queries for use in UI tests or for debugging purposes.

1. When some of these attributes were ported over to the new parsing API, their targets were unnecessarily restricted. I've kept encountering these incorrect "attribute cannot be used" errors all the while HIR analysis happily & correctly dumped the requested data below it. I've now relaxed their targets.
2. Since we now have target checking for the internal attributes I figured that it's unhelpful if we still intentionally crashed on invalid targets, so I've got rid of that.
3. I've always been annoyed that most of these (very old) attributes don't contain the word `dump` in their name (rendering their purpose non-obvious) and that some of their names diverge quite a bit from the corresponding query name. I've now rectified that. The new names take longer to type but it's still absolutely acceptable imo.

---

I haven't renamed all of the TEST attributes to follow the `rustc_dump_` scheme since that's quite tedious. If it's okay with you I'd like to postpone that (e.g., `rustc_{def_path,hidden_type…,layout,regions,symbol_name}`).

I've noticed that the parsers for TEST attrs are spread across `rustc_dump.rs`, `rustc_internal.rs` & `test_attrs.rs` which is a bit confusing. Since the new names are prefixed with `rustc_dump_` I've moved their parsers into `rustc_dump.rs` but of course they are still TEST attrs. IIRC, `test_attrs.rs` also contains non-`rustc_`-TEST attrs, so we can't just merge these two files. I guess that'll sort itself out in the future when I tackle the other internal TEST attrs.

r\? Jana || Jonathan
2026-03-04 19:30:39 +01:00
Jonathan Brouwer bef489b0ce Rollup merge of #152943 - CoCo-Japan-pan:impl-restriction-parse, r=Urgau,jhpratt
Parse `impl` restrictions

This PR implements the parsing logic for `impl` restrictions (e.g., `pub impl(crate) trait Foo {}`) as proposed in [RFC 3323](https://rust-lang.github.io/rfcs/3323-restrictions.html).
As the first step of the RFC implementation, this PR focuses strictly on the parsing phase. The new syntax is guarded by the `#![feature(impl_restriction)]` feature gate.
This implementation basically follows the pattern used in rust-lang/rust#141754.

r? @jhpratt
2026-03-03 13:08:43 +01:00
Jonathan Brouwer ef4cff2ea3 Rollup merge of #153015 - joboet:atomic_alias_generic, r=jhpratt
core: make atomic primitives type aliases of `Atomic<T>`

Tracking issue: https://github.com/rust-lang/rust/issues/130539

This makes `AtomicI32` and friends type aliases of `Atomic<T>` by encoding their alignment requirements via the use of an internal `Storage` associated type. This is also used to encode that `AtomicBool` store a `u8` internally.

Modulo the `Send`/`Sync` implementations, this PR does not move any trait implementations, methods or associated functions – I'll leave that for another PR.
2026-03-02 20:10:34 +01:00
León Orell Valerian Liehr 722fcbb72e Rename #[rustc_object_lifetime_default] to #[rustc_dump_object_lifetime_defaults] 2026-03-02 19:31:15 +01:00
León Orell Valerian Liehr 6af78890bc Rename #![rustc_variance_of_opaques] to #![rustc_dump_variances_of_opaques] 2026-03-02 19:31:15 +01:00
León Orell Valerian Liehr 6bb6b11d9d Rename #[rustc_variance] to #[rustc_dump_variances] 2026-03-02 19:31:15 +01:00
León Orell Valerian Liehr c3a40e26e4 Rename #[rustc_outlives] to #[rustc_dump_inferred_outlives] 2026-03-02 19:31:14 +01:00
Waffle Lapkin 7cefcb41ff add an adt flag for MaybeDangling 2026-03-02 14:42:53 +01:00
joboet 95e571ded1 update references to Atomic in diagnostics
... and remove some unused diagnostic items.
2026-03-02 00:23:23 +01:00
bors ba1567989e Auto merge of #153217 - JonathanBrouwer:rollup-iXVG70B, r=JonathanBrouwer
Rollup of 12 pull requests

Successful merges:

 - rust-lang/rust#153211 (`rust-analyzer` subtree update)
 - rust-lang/rust#149027 (Improve cross-crate trait impl param mismatch suggestions )
 - rust-lang/rust#152730 (add field representing types)
 - rust-lang/rust#153136 (Correctly handle `#[doc(alias = "...")]` attribute on inlined reexports)
 - rust-lang/rust#152165 (Normalize capture place `ty`s to prevent ICE)
 - rust-lang/rust#152615 (refactor 'valid for read/write' definition: exclude null)
 - rust-lang/rust#153109 (Fix LegacyKeyValueFormat report from docker build: aarch64-gnu-debug)
 - rust-lang/rust#153172 (Fix comment about placeholders)
 - rust-lang/rust#153187 (Fix ICE when macro-expanded extern crate shadows std)
 - rust-lang/rust#153190 (Don't allow subdiagnostic to use variables from their parent)
 - rust-lang/rust#153200 (Remove redundant clone)
 - rust-lang/rust#153216 (mark two polonius tests as known-bug)
2026-02-28 12:23:16 +00:00
Jonathan Brouwer 1acf1c5367 Rollup merge of #152730 - BennoLossin:field-projections-lang-item, r=oli-obk
add field representing types

*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/152730)*

> [!NOTE]
> This is a rewrite of #146307 by using a lang item instead of a custom `TyKind`. We still need a `hir::TyKind::FieldOf` variant, because resolving the field name cannot be done before HIR construction. The advantage of doing it this way is that we don't need to make any changes to types after HIR (including symbol mangling). At the very beginning of this feature implementation, I tried to do it using a lang item, but then quickly abandoned the approach, because at that time I was still intending to support nested fields.

Here is a [range-diff](https://triagebot.infra.rust-lang.org/gh-range-diff/rust-lang/rust/605f49b27444a738ea4032cb77e3bdc4eb811bab..d15f5052095b3549111854a2555dd7026b0a729e/605f49b27444a738ea4032cb77e3bdc4eb811bab..f5f42d1e03495dbaa23671c46b15fccddeb3492f) between the two PRs

---

# Add Field Representing Types (FRTs)

This PR implements the first step of the field projection lang experiment (Tracking Issue: rust-lang/rust#145383). Field representing types (FRTs) are a new kind of type. They can be named through the use of the `field_of!` macro with the first argument being the type and the second the name of the field (or variant and field in the case of an enum). No nested fields are supported.

FRTs natively implement the `Field` trait that's also added in this PR. It exposes information about the field such as the type of the field, the type of the base (i.e. the type that contains the field) and the offset within that base type. Only fields of non-packed structs are supported, fields of enums an unions have unique types for each field, but those do not implement the `Field` trait.

This PR was created in collaboration with @dingxiangfei2009, it wouldn't have been possible without him, so huge thanks for mentoring me!

I updated my library solution for field projections to use the FRTs from `core` instead of creating my own using the hash of the name of the field. See the [Rust-for-Linux/field-projection `lang-experiment` branch](https://github.com/Rust-for-Linux/field-projection/tree/lang-experiment).

## API added to `core::field`

```rust
pub unsafe trait Field {
    type Base;

    type Type;

    const OFFSET: usize;
}

pub macro field_of($Container:ty, $($fields:expr)+ $(,)?);
```

Along with a perma-unstable type that the compiler uses in the expansion of the macro:

```rust
#[unstable(feature = "field_representing_type_raw", issue = "none")]
pub struct FieldRepresentingType<T: ?Sized, const VARIANT: u32, const FIELD: u32> {
    _phantom: PhantomData<T>,
}
```

## Explanation of Field Representing Types (FRTs)

FRTs are used for compile-time & trait-level reflection for fields of structs & tuples. Each struct & tuple has a unique compiler-generated type nameable through the `field_of!` macro. This type natively contains information about the field such as the outermost container, type of the field and its offset. Users may implement additional traits on these types in order to record custom information (for example a crate may define a [`PinnableField` trait](https://github.com/Rust-for-Linux/field-projection/blob/lang-experiment/src/marker.rs#L9-L23) that records whether the field is structurally pinned).

They are the foundation of field projections, a general operation that's generic over the fields of a struct. This genericism needs to be expressible in the trait system. FRTs make this possible, since an operation generic over fields can just be a function with a generic parameter `F: Field`.

> [!NOTE]
> The approach of field projections has changed considerably since this PR was opened. In the end we might not need FRTs, so this API is highly experimental.

FRTs should act as though they were defined as `struct MyStruct_my_field<StructGenerics>;` next to the struct. So it should be local to the crate defining the struct so that one can implement any trait for the FRT from that crate. The `Field` traits should be implemented by the compiler & populated with correct information (`unsafe` code needs to be able to rely on them being correct).

## TODOs

There are some `FIXME(FRTs)` scattered around the code:
- Diagnostics for `field_of!` can be improved
  - `tests/ui/field_representing_types/nonexistent.rs`
  - `tests/ui/field_representing_types/non-struct.rs`
  - `tests/ui/field_representing_types/offset.rs`
  - `tests/ui/field_representing_types/not-field-if-packed.rs`
  - `tests/ui/field_representing_types/invalid.rs`
- Simple type alias already seem to work, but might need some extra work in `compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs`

r? @oli-obk
2026-02-28 12:52:52 +01:00
bors 1d113d2f30 Auto merge of #152948 - GrigorenkoPV:sym-ascii, r=JonathanBrouwer
pre-intern single-letter `sym::[a-zA-Z]`

As suggested in https://github.com/rust-lang/rust/pull/152624#discussion_r2822059367.

Needs a perf run I guess.
2026-02-28 08:38:11 +00:00
CoCo-Japan-pan a0ccef6f25 Add impl_restriction feature 2026-02-28 13:56:56 +09:00
Benno Lossin 7b428597ff add field representing types 2026-02-27 15:54:20 +01:00
Jonathan Brouwer 5cd5b90a38 Port rustc_autodiff to the attribute parsers 2026-02-26 09:50:36 +01:00
cyrgani f1ec10ecbd deprecate Eq::assert_receiver_is_total_eq and emit a FCW on manual impls 2026-02-25 09:12:42 +00:00
mejrs f944436c29 port over diagnostic::on_unimplemented 2026-02-24 10:50:38 +01:00
Jonathan Brouwer 1d6e7ec8d4 Rollup merge of #152003 - 9SonSteroids:trait_info_of, r=oli-obk
Reflection TypeId::trait_info_of

*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/152003)*

This is for https://github.com/rust-lang/rust/issues/146922.

As https://github.com/rust-lang/rust/pull/151236 was requested to be remade by someone I implemented the functionality as `TypeId::trait_info_of` which additionally allows getting the vtable pointer to build `dyn` Objects in recursive reflection.

It allows checking if a TypeId implements a trait. Since this is my first PR feel free to tell me if there are any formal issues.
2026-02-23 20:46:11 +01:00
Stuart Cook 8c96521c99 Rollup merge of #152987 - Zoxc:hashstable-derives, r=JonathanBrouwer
Use `HashStable` derive in more places

This applies `HashStable` derive in a couple more places. Also `stable_hasher` is declared for `HashStable_NoContext`.
2026-02-23 13:32:01 +11:00
John Kåre Alsaker 912c7d31d2 Use HashStable derive in more places 2026-02-22 21:01:27 +01:00
Folkert de Vries 14d29f9ae2 Stabilize cfg_select 2026-02-22 19:59:25 +01:00
Pavel Grigorenko abcdef0640 pre-intern single-letter sym::[a-zA-Z] 2026-02-22 01:00:22 +03:00
jasper3108 7857058a6b nix vtable_for intrinsic 2026-02-20 10:16:36 +01:00
jasper3108 01627b7441 Support getting TypeId's Trait and vtable 2026-02-20 10:16:36 +01:00
Cameron Steffen 0f9b166a6f Audit Symbols 2026-02-19 19:27:33 -06:00
Jonathan Brouwer 610e63b9ba Rollup merge of #152558 - Unique-Usman:ua/decmacrorepeatable, r=estebank
rustc_expand: improve diagnostics for non-repeatable metavars in repetition

Enhance `NoSyntaxVarsExprRepeat` by suggesting similarly named metavariables, distinguishing repeatable vs non-repeatable bindings, and listing available repeatable variables when no match exists.
2026-02-19 10:56:37 +01:00
bors fbd6934114 Auto merge of #152825 - JonathanBrouwer:rollup-0YvwE70, r=JonathanBrouwer
Rollup of 18 pull requests

Successful merges:

 - rust-lang/rust#152799 (Subtree sync for rustc_codegen_cranelift)
 - rust-lang/rust#152814 (stdarch subtree update)
 - rust-lang/rust#151059 (x86: support passing `u128`/`i128` to inline assembly)
 - rust-lang/rust#152097 (Suggest local variables for captured format args)
 - rust-lang/rust#152734 (Respect the `--ci` flag in more places in bootstrap)
 - rust-lang/rust#151703 (Fix ICE in transmutability error reporting when type aliases are normalized)
 - rust-lang/rust#152173 (Reflection TypeKind::FnPtr)
 - rust-lang/rust#152564 (Remove unnecessary closure.)
 - rust-lang/rust#152628 (tests: rustc_public: Check const allocation for all variables (1 of 11 was missing))
 - rust-lang/rust#152658 (compiletest: normalize stderr before SVG rendering)
 - rust-lang/rust#152766 (std::r#try! - avoid link to nightly docs)
 - rust-lang/rust#152780 (Remove some clones in deriving)
 - rust-lang/rust#152787 (Add a mir-opt test for alignment check generation [zero changes outside tests])
 - rust-lang/rust#152790 (Fix incorrect target in aarch64-unknown-linux-gnu docs)
 - rust-lang/rust#152792 (Fix an ICE while checking param env shadowing on an erroneous trait impl)
 - rust-lang/rust#152793 (Do no add -no-pie on Windows)
 - rust-lang/rust#152803 (Avoid delayed-bug ICE for malformed diagnostic attrs)
 - rust-lang/rust#152806 (interpret: fix comment typo)
2026-02-19 04:18:20 +00:00
Jonathan Brouwer 5d6c830832 Rollup merge of #152173 - 9SonSteroids:fn_ptr_type_info, r=oli-obk
Reflection TypeKind::FnPtr

This is for https://github.com/rust-lang/rust/issues/146922.

Const-eval currently lacks full support for function pointer (fn) types. We should implement handling of FnPtr TypeKind, covering safe and unsafe functions, Rust and custom ABIs, input and output types, higher-ranked lifetimes, and variadic functions.
2026-02-18 22:19:49 +01:00
bors e0cb264b81 Auto merge of #141295 - Kivooeo:if-let-guard-stable, r=fee1-dead,est31
Stabilize `if let` guards (`feature(if_let_guard)`)



## Summary

This proposes the stabilization of `if let` guards (tracking issue: rust-lang/rust#51114, RFC: rust-lang/rfcs#2294). This feature allows `if let` expressions to be used directly within match arm guards, enabling conditional pattern matching within guard clauses.

## What is being stabilized

The ability to use `if let` expressions within match arm guards.

Example:

```rust
enum Command {
    Run(String),
    Stop,
    Pause,
}

fn process_command(cmd: Command, state: &mut String) {
    match cmd {
        Command::Run(name) if let Some(first_char) = name.chars().next() && first_char.is_ascii_alphabetic() => {
            // Both `name` and `first_char` are available here
            println!("Running command: {} (starts with '{}')", name, first_char);
            state.push_str(&format!("Running {}", name));
        }
        Command::Run(name) => {
            println!("Cannot run command '{}'. Invalid name.", name);
        }
        Command::Stop if state.contains("running") => {
            println!("Stopping current process.");
            state.clear();
        }
        _ => {
            println!("Unhandled command or state.");
        }
    }
}
```

## Motivation

The primary motivation for `if let` guards is to reduce nesting and improve readability when conditional logic depends on pattern matching. Without this feature, such logic requires nested `if let` statements within match arms:

```rust
// Without if let guards
match value {
    Some(x) => {
        if let Ok(y) = compute(x) {
            // Both `x` and `y` are available here
            println!("{}, {}", x, y);
        }
    }
    _ => {}
}

// With if let guards
match value {
    Some(x) if let Ok(y) = compute(x) => {
        // Both `x` and `y` are available here
        println!("{}, {}", x, y);
    }
    _ => {}
}
```

## Implementation and Testing

The feature has been implemented and tested comprehensively across different scenarios:

### Core Functionality Tests

**Scoping and variable binding:**
- [`scope.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/scope.rs) - Verifies that bindings created in `if let` guards are properly scoped and available in match arms
- [`shadowing.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/shadowing.rs) - Tests that variable shadowing works correctly within guards
- [`scoping-consistency.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/scoping-consistency.rs) - Ensures temporaries in guards remain valid for the duration of their match arms

**Type system integration:**
- [`type-inference.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/type-inference.rs) - Confirms type inference works correctly in `if let` guards  
- [`typeck.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/typeck.rs) - Verifies type mismatches are caught appropriately

**Pattern matching semantics:**
- [`exhaustive.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/exhaustive.rs) - Validates that `if let` guards are correctly handled in exhaustiveness analysis
- [`move-guard-if-let.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let.rs) and [`move-guard-if-let-chain.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.rs) - Test that conditional moves in guards are tracked correctly by the borrow checker

### Error Handling and Diagnostics

- [`warns.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/warns.rs) - Tests warnings for irrefutable patterns and unreachable code in guards
- [`parens.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/parens.rs) - Ensures parentheses around `let` expressions are properly rejected
- [`macro-expanded.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/macro-expanded.rs) - Verifies macro expansions that produce invalid constructs are caught
- [`guard-mutability-2.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/guard-mutability-2.rs) - Tests mutability and ownership violations in guards
- [`ast-validate-guards.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2497-if-let-chains/ast-validate-guards.rs) - Validates AST-level syntax restrictions

### Drop Order and Temporaries

**Key insight:** Unlike `let_chains` in regular `if` expressions, `if let` guards do not have drop order inconsistencies because:
1. Match guards are clearly scoped to their arms
2. There is no "else block" equivalent that could cause temporal confusion

- [`drop-order.rs`](https://github.com/rust-lang/rust/blob/5796073c134eaac30475f9a19462c4e716c9119c/tests/ui/rfcs/rfc-2294-if-let-guard/drop-order.rs) - Check drop order of temporaries create in match guards
- [`compare-drop-order.rs`](https://github.com/rust-lang/rust/blob/aef3f5fdf052fbbc16e174aef5da6d50832ca316/tests/ui/rfcs/rfc-2294-if-let-guard/compare-drop-order.rs) - Compares drop order between `if let` guards and nested `if let` in match arms, confirming they behave identically across all editions
- rust-lang/rust#140981 - A complicated drop order test involved `let chain` was made by @est31
- [`drop-order-comparisons-let-chains.rs`](https://github.com/rust-lang/rust/blob/902b4d28783e03e231d8513082cc30c4fcce5d95/tests/ui/drop/drop-order-comparisons-let-chains.rs) - Compares drop order between `let chains` in `if let guard` and regular `if` expressions
- [`if-let-guards.rs`](https://github.com/rust-lang/rust/blob/5650d716e0589e2e145ce9027f35bd534e5f862a/tests/ui/drop/if-let-guards.rs) - Test correctness of drop order for bindings and temporaries
- [`if-let-guards-2`](https://github.com/rust-lang/rust/blob/3a6c8c8f3d7ae654fdb6ce1255182bda21680655/tests/ui/drop/if-let-guards-2.rs) - The same test as above but more comprehensive and tests more interactions between different features and their drop order, checking that drop order is correct, created by @traviscross 

## Edition Compatibility

This feature stabilizes on all editions, unlike `let chains` which was limited to edition 2024. This is safe because:

1. `if let` guards don't suffer from the drop order issues that affected `let chains` in regular `if` expressions
2. The scoping is unambiguous - guards are clearly tied to their match arms
3. Extensive testing confirms identical behavior across all editions

## Interactions with Future Features

The lang team has reviewed potential interactions with planned "guard patterns" and determined that stabilizing `if let` guards now does not create obstacles for future work. The scoping and evaluation semantics established here align with what guard patterns will need.

## Unresolved Issues

- [x] - rust-lang/rust#140981
- [x] - added tests description by @jieyouxu request
- [x] - Concers from @scottmcm about stabilizing this across all editions
- [x] - check if drop order in all edition when using `let chains` inside `if let` guard is the same
- [x] - interactions with guard patters
- [x] - pattern bindings drops before guard bindings https://github.com/rust-lang/rust/pull/143376
- [x] - documentaion (https://github.com/rust-lang/reference/pull/1957)
- [ ] (non-blocking) add tests for [this](https://github.com/rust-lang/rust/issues/145237) and [this](https://github.com/rust-lang/rust/pull/141295#issuecomment-3173059821)

---

**Related:**
- Tracking Issue: rust-lang/rust#51114  
- RFC: rust-lang/rfcs#2294
- Documentation PR: https://github.com/rust-lang/reference/pull/1957
2026-02-18 20:49:50 +00:00
jasper3108 7287be9006 Implement reflection support for function pointer types and add tests
- Implement handling of FnPtr TypeKind in const-eval, including:
  - Unsafety flag (safe vs unsafe fn)
  - ABI variants (Rust, Named(C), Named(custom))
  - Input and output types
  - Variadic function pointers
- Add const-eval tests covering:
  - Basic Rust fn() pointers
  - Unsafe fn() pointers
  - Extern C and custom ABI pointers
  - Functions with multiple inputs and output types
  - Variadic functions
- Use const TypeId checks to verify correctness of inputs, outputs, and payloads
2026-02-18 17:18:16 +01:00
Usman Akinyemi 88e96b8814 rustc_expand: improve diagnostics for non-repeatable metavars in repetition
Enhance `NoSyntaxVarsExprRepeat` by suggesting similarly named
metavariables, distinguishing repeatable vs non-repeatable bindings,
and listing available repeatable variables when no match exists.

Co-authored-by: Esteban Küber <esteban@kuber.com.ar>
Signed-off-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
2026-02-18 20:14:36 +05:30
cyrgani 195b849ea7 remove the explicit error for old rental versions 2026-02-17 20:11:01 +00:00
Stuart Cook 1367126837 Rollup merge of #151783 - mu001999-contrib:impl/final-method, r=fee1-dead
Implement RFC 3678: Final trait methods

Tracking: https://github.com/rust-lang/rust/issues/131179

This PR is based on rust-lang/rust#130802, with some minor changes and conflict resolution.

Futhermore, this PR excludes final methods from the vtable of a dyn Trait.

And some excerpt from the original PR description:
> Implements the surface part of https://github.com/rust-lang/rfcs/pull/3678.
>
> I'm using the word "method" in the title, but in the diagnostics and the feature gate I used "associated function", since that's more accurate.

cc @joshtriplett
2026-02-17 13:02:21 +11:00
bors 3c9faa0d03 Auto merge of #148190 - RalfJung:box_new, r=RalfJung
replace box_new with lower-level intrinsics

The `box_new` intrinsic is super special: during THIR construction it turns into an `ExprKind::Box` (formerly known as the `box` keyword), which then during MIR building turns into a special instruction sequence that invokes the exchange_malloc lang item (which has a name from a different time) and a special MIR statement to represent a shallowly-initialized `Box` (which raises [interesting opsem questions](https://github.com/rust-lang/rust/issues/97270)).

This PR is the n-th attempt to get rid of `box_new`. That's non-trivial because it usually causes a perf regression: replacing `box_new` by naive unsafe code will incur extra copies in debug builds, making the resulting binaries a lot slower, and will generate a lot more MIR, making compilation measurably slower. Furthermore, `vec!` is a macro, so the exact code it expands to is highly relevant for borrow checking, type inference, and temporary scopes.

To avoid those problems, this PR does its best to make the MIR almost exactly the same as what it was before. `box_new` is used in two places, `Box::new` and `vec!`:
- For `Box::new` that is fairly easy: the `move_by_value` intrinsic is basically all we need. However, to avoid the extra copy that would usually be generated for the argument of a function call, we need to special-case this intrinsic during MIR building. That's what the first commit does.
- `vec!` is a lot more tricky. As a macro, its details leak to stable code, so almost every variant I tried broke either type inference or the lifetimes of temporaries in some ui test or ended up accepting unsound code due to the borrow checker not enforcing all the constraints I hoped it would enforce. I ended up with a variant that involves a new intrinsic, `fn write_box_via_move<T>(b: Box<MaybeUninit<T>>, x: T) -> Box<MaybeUninit<T>>`, that writes a value into a `Box<MaybeUninit<T>>` and returns that box again. In exchange we can get rid of somewhat similar code in the lowering for `ExprKind::Box`, and the `exchange_malloc` lang item. (We can also get rid of `Rvalue::ShallowInitBox`; I didn't include that in this PR -- I think @cjgillot has a commit for this somewhere [around here](https://github.com/rust-lang/rust/pull/147862/commits).)

See [here](https://github.com/rust-lang/rust/pull/148190#issuecomment-3457454814) for the latest perf numbers. Most of the regressions are in deep-vector which consists entirely of an invocation of `vec!`, so any change to that macro affects this benchmark disproportionally.

This is my first time even looking at MIR building code, so I am very low confidence in that part of the patch, in particular when it comes to scopes and drops and things like that.

I also had do nerf some clippy tests because clippy gets confused by the new expansion of `vec!` so it makes fewer suggestions when `vec!` is involved.

### `vec!` FAQ

- Why does `write_box_via_move` return the `Box` again? Because we need to expand `vec!` to a bunch of method invocations without any blocks or let-statements, or else the temporary scopes (and type inference) don't work out.
- Why is `box_assume_init_into_vec_unsafe` (unsoundly!) a safe function? Because we can't use an unsafe block in `vec!` as that would necessarily also include the `$x` (due to it all being one big method invocation) and therefore interpret the user's code as being inside `unsafe`, which would be bad (and 10 years later, we still don't have safe blocks for macros like this).
- Why does `write_box_via_move` use `Box` as input/output type, and not, say, raw pointers? Because that is the only way to get the correct behavior when `$x` panics or has control effects: we need the `Box` to be dropped in that case. (As a nice side-effect this also makes the intrinsic safe, which is imported as explained in the previous bullet.)
- Can't we make it safe by having `write_box_via_move` return `Box<T>`? Yes we could, but there's no easy way for the intrinsic to convert its `Box<MaybeUninit<T>>` to a `Box<T>`. Transmuting would be unsound as the borrow checker would no longer properly enforce that lifetimes involved in a `vec!` invocation behave correctly.
- Is this macro truly cursed? Yes, yes it is.
2026-02-16 18:46:10 +00:00
Ralf Jung e5ed8643b6 adjust clippy to fix some of the issues 2026-02-16 17:27:40 +01:00
Ralf Jung 5e65109f21 add write_box_via_move intrinsic and use it for vec!
This allows us to get rid of box_new entirely
2026-02-16 17:27:40 +01:00
Kivooeo 964b63f42e if let guard stabilize 2026-02-16 12:24:15 +00:00
Jacob Pratt 494c6da389 Rollup merge of #150601 - folkertdev:c-variadic-const-eval, r=RalfJung
support c-variadic functions in `rustc_const_eval`

tracking issue: https://github.com/rust-lang/rust/issues/44930

The new `GlobalAlloc::VaList` is used to create an `AllocId` that represents the variable argument list of a frame. The allocation itself does not store any data, all we need is the unique identifier.

The actual variable argument list is stored in `Memory`, and keyed by the `AllocId`. The `Frame` also stores this `AllocId`, so that when a frame is popped, it can deallocate the variable arguments.

At "runtime" a `VaList` value stores a pointer to the global allocation in its first bytes. The provenance on this pointer can be used to retrieve its `AllocId`, and the offset of the pointer is used to store the index of the next argument to read from the variable argument list.

Miri does not yet support `va_arg`, but I think that can be done separetely?

r? @RalfJung
cc @workingjubilee
2026-02-16 04:28:56 -05:00
Folkert de Vries 981dacc34f feature-gate c-variadic definitions and calls in const contexts 2026-02-15 19:54:25 +01:00
bors 2219766af6 Auto merge of #152605 - scottmcm:box-drop-alignment, r=Mark-Simulacrum
Pass alignments through the shim as `Alignment` (not `usize`)

We're using `Layout` on both sides, so might as well skip the transmutes back and forth to `usize`.

The mir-opt test shows that doing so allows simplifying the boxed-slice drop slightly, for example.
2026-02-15 13:38:45 +00:00
Folkert de Vries b935f379b4 implement carryless_mul 2026-02-14 21:23:30 +01:00