Skip to content

Conversation

@BennoLossin
Copy link
Contributor

@BennoLossin BennoLossin commented Sep 7, 2025

Add Field Representing Types (FRTs)

This PR implements the first step of the field projection lang experiment (Tracking Issue: #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.

API added to core::field

pub unsafe trait Field {
    type Base;
    
    type Type;

    const OFFSET: usize;
}

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

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 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).

Design Decisions

During the development several desirable properties of FRTs were discovered. Either due to simplifying the implementation or because of language design reasons. These decisions are:

  • FRTs are inhabited ZSTs, they have the same layout as ()

    • They only contain type information via the Field trait. Their only use of the values is a future ergonomics change that allows skipping turbofish syntax.
    • This simplifies const-eval.
    • They are thus also Freeze
  • The coherence check of FRTs amounts to checking coherence of the base type.

    So field_of!(Foo, bar) is local if Foo is local (Bar is allowed to be foreign). Fundamental types are not handled specially, so field_of!(MaybeUninit<Struct>, value) still is local to core (aside from the fact that non-visible fields cannot be accessed in the first place).

  • Traits may be implemented for FRTs in the usual way (so if the FRT or the trait is local). There is an exception:

    • Drop: since FRTs are uninhabited, having a Drop impl doesn't really make sense. It also would have required duplicating a lot of logic from ADTs and as such it simplified the implementation.
  • The Field trait is not user-implementable

    • this also can be lifted in the future, but for now only FRTs will implement it.
  • FRTs implement all auto traits as well as Copy and Clone.

TODOs

There are several FIXME(FRTs) scattered around the code:

  • rustdoc doesn't yet support them, this can be implemented later
    • src/librustdoc/json/conversions.rs
  • Debuginfo and symbol mangling is not implemented, for this PR they aren't important, but later we should implement it
    • compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
    • compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
    • compiler/rustc_symbol_mangling/src/v0.rs
  • 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

@rustbot
Copy link
Collaborator

rustbot commented Sep 7, 2025

r? @lcnr

rustbot has assigned @lcnr.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-rustdoc-json Area: Rustdoc JSON backend PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Sep 7, 2025
@rustbot
Copy link
Collaborator

rustbot commented Sep 8, 2025

changes to the core type system

cc @compiler-errors, @lcnr

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Some changes occurred in diagnostic error codes

cc @GuillaumeGomez

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred in compiler/rustc_sanitizers

cc @rcvalle

HIR ty lowering was modified

cc @fmease

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in exhaustiveness checking

cc @Nadrieril

This PR changes MIR

cc @oli-obk, @RalfJung, @JakobDegen, @vakaras

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

This PR changes rustc_public

cc @oli-obk, @celinval, @ouz-a

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

Some changes occurred to the intrinsics. Make sure the CTFE / Miri interpreter
gets adapted for the changes, if necessary.

cc @rust-lang/miri, @RalfJung, @oli-obk, @lcnr

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Copy link
Contributor Author

@BennoLossin BennoLossin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some changes to symbol mangling & constant names that I'm not sure how they resulted from my changes. Anybody has any idea?

View changes since this review

@rustbot
Copy link
Collaborator

rustbot commented Sep 9, 2025

Some changes occurred to constck

cc @fee1-dead

@rust-log-analyzer

This comment has been minimized.

@rustbot
Copy link
Collaborator

rustbot commented Sep 9, 2025

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

@rust-log-analyzer

This comment has been minimized.

@tmandry tmandry added the F-field_projections `#![feature(field_projections)]` label Sep 9, 2025
Copy link
Member

@RalfJung RalfJung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you ensure you have a test that is generic over the field and that queries the offset? That would hit all these points I just mentioned here (or at least some of them), and anyway seems like a very non-trivial case to test.

Or... wait the intrinsic is only used to define that one associated const? I don't know exactly when and how we normalize those but it may be that we indeed never see that MIR in its generic form then...

The test may have to invoke the intrinsic directly to trigger the case I am thinking of.

View changes since this review

@rustbot
Copy link
Collaborator

rustbot commented Jan 29, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-rustdoc-json Area: Rustdoc JSON backend F-field_projections `#![feature(field_projections)]` I-lang-radar Items that are on lang's radar and will need eventual work or consideration. PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-clippy Relevant to the Clippy team. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. T-rustfmt Relevant to the rustfmt team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants