Skip to content

add field representing types#152730

Open
BennoLossin wants to merge 2 commits intorust-lang:mainfrom
BennoLossin:field-projections-lang-item
Open

add field representing types#152730
BennoLossin wants to merge 2 commits intorust-lang:mainfrom
BennoLossin:field-projections-lang-item

Conversation

@BennoLossin
Copy link
Contributor

@BennoLossin BennoLossin commented Feb 16, 2026

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 between the two PRs


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)+ $(,)?);

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

#[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 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

@rustbot
Copy link
Collaborator

rustbot commented Feb 16, 2026

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

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

HIR ty lowering was modified

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels Feb 16, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 16, 2026

oli-obk is not on the review rotation at the moment.
They may take a while to respond.

@rust-log-analyzer

This comment has been minimized.

@BennoLossin BennoLossin force-pushed the field-projections-lang-item branch from fe3fa8b to f5f42d1 Compare February 16, 2026 20:53
@rustbot
Copy link
Collaborator

rustbot commented Feb 16, 2026

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend T-clippy Relevant to the Clippy team. 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. labels Feb 16, 2026
@rust-log-analyzer

This comment has been minimized.

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

Labels

A-rustdoc-json Area: Rustdoc JSON backend 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-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.

4 participants