Commit Graph

2800 Commits

Author SHA1 Message Date
Guillaume Gomez 67ab3ac423 Rollup merge of #154043 - RalfJung:simd-min-max, r=Amanieu,calebzulawski,antoyo
simd_fmin/fmax: make semantics and name consistent with scalar intrinsics

This is the SIMD version of https://github.com/rust-lang/rust/pull/153343: change the documented semantics of the SIMD float min/max intrinsics to that of the scalar intrinsics, and also make the name consistent. The overall semantic change this amounts to is that we restrict the non-determinism: the old semantics effectively mean "when one input is an SNaN, the result non-deterministically is a NaN or the other input"; the new semantics say that in this case the other input must be returned. For all other cases, old and new semantics are equivalent. This means all users of these intrinsics that were correct with the old semantics are still correct: the overall set of possible behaviors has become smaller, no new possible behaviors are being added.

In terms of providers of this API:
- Miri, GCC, and cranelift already implement the new semantics, so no changes are needed.
- LLVM is adjusted to use `minimumnum nsz` instead of `minnum`, thus giving us the new semantics.

In terms of consumers of this API:
- Portable SIMD almost certainly wants to match the scalar behavior, so this is strictly a bugfix here.
- Stdarch mostly stopped using the intrinsic, except on nvptx, where arguably the new semantics are closer to what we actually want than the old semantics (https://github.com/rust-lang/stdarch/issues/2056).

Q: Should there be an `f` in the intrinsic name to indicate that it is for floats? E.g., `simd_fminimum_number_nsz`?

Also see https://github.com/rust-lang/rust/issues/153395.
2026-03-29 00:06:50 +01:00
Guillaume Gomez e6f17e4bbb Rollup merge of #153834 - N1ark:generic-float-intrinsics, r=tgross35,RalfJung
Merge `fabsf16/32/64/128` into `fabs::<F>`

Following [a small conversation on Zulip](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/Float.20intrinsics/with/521501401) (and because I'd be interested in starting to contribute on Rust), I thought I'd give a try at merging the float intrinsics :)

This PR just merges `fabsf16`, `fabsf32`, `fabsf64`, `fabsf128`, as it felt like an easy first target.

Notes:
- I'm opening the PR for one intrinsic as it's probably easier if the shift is done one intrinsic at a time, but let me know if you'd rather I do several at a time to reduce the number of PRs.
- Currently this PR increases LOCs, despite being an attempt at simplifying the intrinsics/compilers. I believe this increase is a one time thing as I had to define new functions and move some things around, and hopefully future PRs/commits will reduce overall LoCs
- `fabsf32` and `fabsf64` are `#[rustc_intrinsic_const_stable_indirect]`, while `fabsf16` and `fabsf128` aren't; because `f32`/`f64` expect the function to be const, the generic version must be made indirectly stable too. We'd need to check with T-lang this change is ok; the only other intrinsics where there is such a mismatch is `minnum`, `maxnum` and `copysign`.
- I haven't touched libm because I'm not familiar with how it works; any guidance would be welcome!
2026-03-29 00:06:50 +01:00
Ralf Jung c47e0e1d72 Rollup merge of #154502 - RalfJung:interpret-untuple-check, r=oli-obk
interpret: ensure that untupled arguments are actually tuples

Something seems very wrong if they are not. ;)
2026-03-28 13:15:54 +01:00
Ralf Jung f50103eed2 Rollup merge of #153613 - RalfJung:interpret-report, r=oli-obk
interpreter error reporting: remove arguments that are always the same

This `report` function is called twice and both callers use the same `span` and `get_span_and_frames`... so let's just fix those arguments inside the function, no need to be more generic than this.
2026-03-28 13:15:49 +01:00
Ralf Jung ad298d5a81 interpret: ensure that untupled arguments are actually tuples 2026-03-28 12:07:49 +01:00
Jonathan Brouwer b5e4b4ca79 Rollup merge of #154269 - RalfJung:miri-recursive-shallow, r=saethlin
miri recursive validation: only check one layer deep

As has been proposed in https://github.com/rust-lang/unsafe-code-guidelines/issues/414, let's see what happens if we make recursive checking in Miri shallow: we treat whatever is behind a reference as if it was inside `MaybeDangling`, which means nested references do not have to be dereferenceable.

This changes the meaning of the original flag -- I don't think it is worth supporting multiple variants of recursive checking (it'd require a bunch of new plumbing), and this seems to be the strictest variant that still has any traction in the discussion.
2026-03-25 19:52:52 +01:00
Jonathan Brouwer 27f9b7ca59 Rollup merge of #154263 - RalfJung:interpret-arg-passing-spans, r=oli-obk
interpret: when passing an argument fails, point at that argument

For a long time now, we did some contortions so that when something goes wrong while initializing the arguments for a function, we point at the call site rather than the callee. Historically, this had to be done because the "current location" in the callee pointed at the first instruction, which would obviously be nonsense. A while ago we gained the ability in the interpreter for the "current location" to be just a span that we point at for errors, but we never reevaluated the decision for how spans are handled during function calls. (We did use this "just a span" location for [errors during the initial stack frame setup](https://github.com/rust-lang/rust/commit/d21e0118d0eefc8b0073fa47fa16699d37047abf), but not for argument initialization.)

There's no always-great choice for pointing at the caller vs the callee: when they disagree about the type of an argument, either side could be wrong. If We do *two* typed copies in that case, one at the caller type and one at the callee type. Arguably we should point at the one that goes wrong, but we don't have a good way to expose that.

What ultimately pushed me over the edge towards pointing at the callee are two points:
- This provides strictly more information. if we point at the callee, the caller is available in the stacktrace. But if we point at the caller, then it might be impossible to figure out the actual callee if a function pointer or dyn call is involved.
- As part of resolving some long-standing questions around retags I am moving retagging to become part of validation, which means the retag and protector initialization of function arguments will happen during argument initialization. These currently point at the argument inside the callee, which I think is strictly preferable for these errors.

The diff will be much smaller with whitespace changes hidden.
2026-03-25 19:52:51 +01:00
Jonathan Brouwer ab6401749a Rollup merge of #154097 - RalfJung:validity-error, r=oli-obk
improve validation error messages: show surrounding type

Also, for dyn-downcast show the type we're downcasting to.

r? @oli-obk
2026-03-24 18:14:15 +01:00
Ralf Jung 5f68044357 miri recursive checking: only check one layer deep 2026-03-24 07:59:37 +01:00
Jonathan Brouwer 62a3eab283 Rollup merge of #154093 - RalfJung:validity-maybedangling, r=WaffleLapkin
const validity checking: do not recurse to references inside MaybeDangling

This arguably should be allowed, but we currently reject it:
```rust
#![feature(maybe_dangling)]
use std::mem::MaybeDangling;

const X: MaybeDangling<&bool> = unsafe { std::mem::transmute(&5u8) };
```

r? @WaffleLapkin
2026-03-23 20:18:34 +01:00
Ralf Jung c0e6c763a9 interpret: when passing an argument fails, point at that argument 2026-03-23 18:25:09 +01:00
bors eb9d3caf05 Auto merge of #154253 - JonathanBrouwer:rollup-LLZUsz2, r=JonathanBrouwer
Rollup of 13 pull requests

Successful merges:

 - rust-lang/rust#154241 (`rust-analyzer` subtree update)
 - rust-lang/rust#153686 (`std`: include `dlmalloc` for all non-wasi Wasm targets)
 - rust-lang/rust#154105 (bootstrap: Pass `--features=rustc` to rustc_transmute)
 - rust-lang/rust#153069 ([BPF] add target feature allows-misaligned-mem-access)
 - rust-lang/rust#154085 (Parenthesize or-patterns in prefix pattern positions in pretty printer)
 - rust-lang/rust#154191 (refactor RangeFromIter overflow-checks impl)
 - rust-lang/rust#154207 (Refactor query loading)
 - rust-lang/rust#153540 (drop derive helpers during attribute parsing)
 - rust-lang/rust#154140 (Document consteval behavior of ub_checks, overflow_checks, is_val_statically_known.)
 - rust-lang/rust#154161 (On E0277 tweak help when single type impls traits)
 - rust-lang/rust#154218 (interpret/validity: remove unreachable error kind)
 - rust-lang/rust#154225 (diagnostics: avoid ICE in confusable_method_name for associated functions)
 - rust-lang/rust#154228 (Improve inline assembly error messages)
2026-03-23 15:46:13 +00:00
Jonathan Brouwer 49e2983d6d Rollup merge of #153582 - mehdiakiki:simplify-find-attr-hir-id, r=JonathanBrouwer
Simplify find_attr! for HirId usage

Add a `HasAttrs<'tcx, Tcx>` trait to `rustc_hir` that allows `find_attr!` to accept `DefId`, `LocalDefId`, `OwnerId`, and `HirId` directly, instead of requiring callers to manually fetch the attribute slice first.

Before:
  `find_attr!(tcx.hir_attrs(hir_id), SomeAttr)`

After:
  `find_attr!(tcx, hir_id, SomeAttr)`

The trait is defined in `rustc_hir` with a generic `Tcx` parameter to avoid a dependency cycle (`rustc_hir` cannot depend on `rustc_middle`). The four concrete impls for `TyCtxt` are in `rustc_middle`.

Fixes https://github.com/rust-lang/rust/issues/153103
2026-03-23 12:14:56 +01:00
Ralf Jung be8dee1141 interpret/validity: remove unreachable error kind 2026-03-22 17:36:39 +01:00
Ralf Jung 05834b2d6b improve validation error messages: show surrounding type, and more info on dyn-downcast 2026-03-19 16:37:00 +01:00
Ralf Jung b3e4ebd9d2 const validity checking: do not recurse to references inside MaybeDangling 2026-03-19 13:46:31 +01:00
Ralf Jung 986a280644 simd_fmin/fmax: make semantics and name consistent with scalar intrinsics 2026-03-18 15:17:56 +01:00
N1ark abb5228ec1 Merge fabsfN into fabs::<F>
Add `bounds::FloatPrimitive`

Exhaustive float pattern match

Fix GCC

use span bugs
2026-03-16 21:49:04 +00:00
Ralf Jung c7220f423b rename min/maxnum intrinsics to min/maximum_number and fix their LLVM lowering 2026-03-15 14:53:00 +01:00
Ralf Jung 46e3c4d258 further cleanup and deduplication 2026-03-12 08:02:18 +01:00
Ralf Jung 5064056dd3 interpreter error reporting: remove arguments that are always the same 2026-03-12 08:01:03 +01:00
randomicon00 858b82da3b Simplify find_attr! for HirId usage
Add a HasAttrs<'tcx, Tcx> trait to rustc_hir that allows find_attr! to
accept DefId, LocalDefId, OwnerId, and HirId directly, instead of
requiring callers to manually fetch the attribute slice first.

The trait is defined in rustc_hir with a generic Tcx parameter to avoid
a dependency cycle (rustc_hir cannot depend on rustc_middle). The four
concrete impls for TyCtxt are in rustc_middle.
2026-03-11 20:31:34 -04:00
Jonathan Brouwer 77134bd3e2 Rollup merge of #153611 - RalfJung:interp-error-strings, r=oli-obk
interpret: go back to regular string interpolation for error messages

Using the translatable diagnostic infrastructure adds a whole lot of boilerplate which isn't actually useful for const-eval errors, so let's get rid of it. This effectively reverts https://github.com/rust-lang/rust/pull/111677. That PR effectively added 1000 lines and this PR only removes around 600 -- the difference is caused by (a) keeping some of the types around for validation, where we can use them to share error strings and to trigger the extra help for pointer byte shenanigans during CTFE, and (b) this not being a full revert of rust-lang/rust#111677; I am not touching diagnostics outside the interpreter such as all the const-checking code which also got converted to fluent in the same PR.

The last commit does something similar for `LayoutError`, which also helps deduplicate a bunch of error strings. I can make that into a separate PR if you prefer.

r? @oli-obk
Fixes https://github.com/rust-lang/rust/issues/113117
Fixes https://github.com/rust-lang/rust/issues/116764
Fixes https://github.com/rust-lang/rust/issues/112618
2026-03-11 22:05:44 +01:00
Ralf Jung 90f7d7e074 clean up some unused leftovers 2026-03-11 13:53:40 +01:00
Ralf Jung 94361fba3e interpret: go back to regular string interpolation for error messages 2026-03-11 13:53:40 +01:00
Jonathan Brouwer 5999ec3328 Rollup merge of #153408 - RalfJung:tag-read-must-be-valid, r=oli-obk
miri: make read_discriminant UB when the tag is not in the validity range of the tag field

Arguably, reading an enum discriminant is an operation that uses the "type" of the discriminant field -- and therefore it should fail when the value in that field isn't valid at that type. Therefore, code like this should be UB:
```rust
fn main() {
    unsafe {
        let x = 12u8;
        let x_ptr: *const u8 = &x;
        let cast_ptr = x_ptr as *const Option<bool>;
        // Reading the discriminant should fail since the tag value is not in the valid
        // range for the tag field.
        let _val = matches!(*cast_ptr, None);
        //~^ ERROR: invalid tag
    }
}
```
However, Miri currently sees no UB here. (MiniRust does see UB.) This is because we never actually check whether the tag we read is in the validity range for its field. So let's add such a check, and a corresponding test.

In fact, we have to do this check, since the codegen backend adds range metadata on the discriminant load, as can be seen in [this example](https://play.rust-lang.org/?version=stable&mode=release&edition=2024&gist=02ef5e80fdfe61540e44198dd827b630). In other words, the above code has UB in LLVM IR but not in Miri, which is a critical Miri bug.
2026-03-11 10:58:51 +01:00
bors b2fabe39bd Auto merge of #153673 - JonathanBrouwer:rollup-cGOKonI, r=JonathanBrouwer
Rollup of 7 pull requests

Successful merges:

 - rust-lang/rust#153560 (Introduce granular tidy_ctx's check in extra_checks)
 - rust-lang/rust#153666 (Add a regression test for rust-lang/rust#153599)
 - rust-lang/rust#153493 (Remove `FromCycleError` trait)
 - rust-lang/rust#153549 (tests/ui/binop: add annotations for reference rules)
 - rust-lang/rust#153641 (Move `Spanned`.)
 - rust-lang/rust#153663 (Remove `TyCtxt::node_lint` method and `rustc_middle::lint_level` function)
 - rust-lang/rust#153664 (Add test for rust-lang/rust#109804)
2026-03-11 05:12:10 +00:00
Jonathan Brouwer 4af0d1551a Rollup merge of #153641 - nnethercote:mv-Spanned, r=JonathanBrouwer
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.

r? @JonathanBrouwer
2026-03-10 22:46:56 +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
David Wood db5e2dc248 abi: s/ScalableVector/SimdScalableVector
Renaming to remove any ambiguity as to what "vector" refers to in this
context
2026-03-10 11:52:22 +00:00
Jonathan Brouwer 610ea1d75d Rollup merge of #153398 - folkertdev:const-c-variadic-trailing-zst, r=RalfJung
fix ICE in `const_c_variadic` when passing ZSTs

fixes https://github.com/rust-lang/rust/issues/153351
r? RalfJung

There was a mismatch between the caller and callee ABI where the caller does not pass ZST arguments, but the callee does expect them. Because ZSTs don't implement `VaArgSafe` the program must already be invalid if this comes up.
2026-03-09 17:56:16 +01:00
Waffle Lapkin 76a750a531 miri/const eval: support MaybeDangling 2026-03-09 12:36:19 +01:00
Folkert de Vries 225b7e0012 fix ICE in const_c_variadic when passing ZSTs 2026-03-09 11:52:09 +01:00
Zalathar 985b41d387 Remove the rustc_data_structures::assert_matches! re-exports 2026-03-08 22:02:23 +11:00
bors c7b206bba4 Auto merge of #153383 - nnethercote:overhaul-ensure_ok, r=Zalathar
Overhaul `ensure_ok`

The interaction of `ensure_ok` and the `return_result_from_ensure_ok` query modifier is weird and hacky. This PR cleans it up. Details in the individual commits.

r? @Zalathar
2026-03-08 07:03:35 +00:00
Nicholas Nethercote d4503b017e Overhaul ensure_ok.
`ensure_ok` provides a special, more efficient way of calling a query
when its return value isn't needed. But there is a complication: if the
query is marked with the `return_result_from_ensure_ok` modifier, then
it will return `Result<(), ErrorGuaranteed`. This is clunky and feels
tacked on. It's annoying to have to add a modifier to a query to declare
information present in its return type, and it's confusing that queries
called via `ensure_ok` have different return types depending on the
modifier.

This commit:

- Eliminates the `return_result_from_ensure_ok` modifier. The proc macro
  now looks at the return type and detects if it matches `Result<_,
  ErrorGuarantee>`. If so, it adds the modifier
  `returns_error_guaranteed`. (Aside: We need better terminology to
  distinguish modifiers written by the user in a `query` declaration
  (e.g. `cycle_delayed_bug`) from modifiers added by the proc macro
  (e.g. `cycle_error_handling`.))

- Introduces `ensure_result`, which replaces the use of `ensure_ok` for
  queries that return `Result<_, ErrorGuarantee>`. As a result,
  `ensure_ok` can now only be used for the "ignore the return value"
  case.
2026-03-08 09:39:39 +11:00
Josh Stone 32bae1353e Update cfg(bootstrap) 2026-03-07 10:42:02 -08:00
Jonathan Brouwer f540b27f90 Rollup merge of #153508 - JonathanBrouwer:improved_eager_format, r=GuillaumeGomez
Clean up the eager formatting API

For https://github.com/rust-lang/rust/issues/151366#event-22181360642

Previously eager formatting worked by throwing the arguments into a diag, formatting, then removing the args again. This is ugly so instead we now just do the formatting completely separately.
This PR has nice commits, so I recommend reviewing commit by commit.

r? @GuillaumeGomez
2026-03-07 01:42:37 +01:00
Jonathan Brouwer 4e0b64408c Fix newly detected subdiagnostics using variables from parent 2026-03-06 19:00:25 +01:00
Jonathan Brouwer 10eb844bac Remove eagerly_format_to_string from DiagCtxt 2026-03-06 18:52:11 +01:00
Jonathan Brouwer 828c0c0668 Remove remove_arg from diagnostics 2026-03-06 18:52:11 +01:00
Jonathan Brouwer 77658bcda3 Rollup merge of #152593 - spirali:valtreekind-list, r=lcnr
Box in `ValTreeKind::Branch(Box<[I::Const]>)` changed to `List`

This is related to trait system refactoring. It fixes the FIXME in `ValTreeKind`

```
   // FIXME(mgca): Use a `List` here instead of a boxed slice
    Branch(Box<[I::Const]>),
```

It introduces `Interner::Consts`, changes `Branch(Box<[I::Const]>)` to `Branch(I::Consts)`, and updates all relevant places.

r? lcnr
2026-03-06 18:49:47 +01:00
Ralf Jung b8403383ff miri: make read_discriminant UB when the tag is not in the validity range of the tag field 2026-03-05 12:09:43 +01:00
bors f8704be04f Auto merge of #153416 - JonathanBrouwer:rollup-eezxWTV, r=JonathanBrouwer
Rollup of 12 pull requests



Successful merges:

 - rust-lang/rust#153402 (miri subtree update)
 - rust-lang/rust#152164 (Lint unused features)
 - rust-lang/rust#152801 (Refactor WriteBackendMethods a bit)
 - rust-lang/rust#153196 (Update path separators to be available in const context)
 - rust-lang/rust#153204 (Add `#[must_use]` attribute to `HashMap` and `HashSet` constructors)
 - rust-lang/rust#153317 (Abort after `representability` errors)
 - rust-lang/rust#153276 (Remove `cycle_fatal` query modifier)
 - rust-lang/rust#153300 (Tweak some of our internal `#[rustc_*]` TEST attributes)
 - rust-lang/rust#153396 (use `minicore` in some `run-make` tests)
 - rust-lang/rust#153401 (Migrationg of `LintDiagnostic` - part 7)
 - rust-lang/rust#153406 (Remove a ping for myself)
 - rust-lang/rust#153414 (Rename translation -> formatting)
2026-03-05 00:14:57 +00:00
Jonathan Brouwer d8092147fe Rename translation -> formatting 2026-03-04 17:47:24 +01:00
Alan Egerton 55509a9fe4 Do not deduce parameter attributes during CTFE
`fn_abi_of_instance` can look at function bodies to deduce codegen
optimization attributes (namely `ArgAttribute::ReadOnly` and
`ArgAttribute::CapturesNone`) of indirectly-passed parameters.  This can
lead to cycles when performed during typeck, when such attributes are
irrelevant.

This patch breaks a subquery out from `fn_abi_of_instance`,
`fn_abi_of_instance_no_deduced_attrs`, which returns the ABI before such
parameter attributes are deduced; and that new subquery is used in CTFE
instead.
2026-03-04 16:38:36 +00:00
bors 38c0de8dcb Auto merge of #153050 - JayanAXHF:refactor/change-is-type-const, r=BoxyUwU
refactor(mgca): Change `DefKind::Const` and `DefKind::AssocConst` to have a `is_type_const` flag



Addresses rust-lang/rust#152940 

- Changed `DefKind::Const` and `DefKind::AssocConst` to have a `is_type_const` flag.
- changed `is_type_const` query to check for this flag
- removed `is_rhs_type_const` query

r? @BoxyUwU
2026-02-28 18:27:06 +00:00
JayanAXHF efc150e5b3 refactor(mgca): Change DefKind::Const and DefKind::AssocConst to have a is_type_const flag
* refactor: add `is_type_const` flag to `DefKind::Const` and `AssocConst`
* refactor(cleanup) remove the `rhs_is_type_const` query
* style: fix formatting
* refactor: refactor stuff in librustdoc for new Const and AssocConst
* refactor: refactor clippy for the changes
* chore: formatting
* fix: fix test
* fix: fix suggestions
* Update context.rs

Co-authored-by: Boxy <rust@boxyuwu.dev>
* changed AssocKind::Const to store data about being a type const
2026-02-28 17:27:46 +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
Benno Lossin 7b428597ff add field representing types 2026-02-27 15:54:20 +01:00