Skip to content

Comments

add field representing types#152730

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

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

Conversation

@BennoLossin
Copy link
Contributor

@BennoLossin BennoLossin commented Feb 16, 2026

View all comments

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.

@rust-log-analyzer

This comment has been minimized.

@rust-bors

This comment has been minimized.

@oli-obk oli-obk added the I-types-nominated Nominated for discussion during a types team meeting. label Feb 17, 2026
@BennoLossin BennoLossin force-pushed the field-projections-lang-item branch from 72f9813 to 2c83a72 Compare February 17, 2026 12:14
@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@BennoLossin BennoLossin force-pushed the field-projections-lang-item branch from edbf7d1 to a94a2f8 Compare February 20, 2026 15:14
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 20, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 20, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rust-log-analyzer

This comment has been minimized.

@BennoLossin
Copy link
Contributor Author

I had to move the indexes, since mod ty in layout is nightly-only. Also had to add #[gate_rustc_only] and make the HashStable_Generic conditional on nightly too. Hope all of that is correct.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 20, 2026
@oli-obk
Copy link
Contributor

oli-obk commented Feb 20, 2026

Yep, that looks correct.

Please squash the new commits into the appropriate main ones. Then I'll approve it

@BennoLossin BennoLossin force-pushed the field-projections-lang-item branch from 503326e to e7bae32 Compare February 20, 2026 20:12
@theemathas
Copy link
Contributor

theemathas commented Feb 21, 2026

If we do go with this design with a new #[fundamental] type, we would have to make sure before stabilization that we've implemented absolutely every trait we need on it, since adding a new impl later is a breaking change.

#[unstable(feature = "field_projections", issue = "145383")]
#[rustc_deny_explicit_impl]
#[rustc_dyn_incompatible_trait]
pub unsafe trait Field: Send + Sync + Copy + Sized {
Copy link
Contributor

Choose a reason for hiding this comment

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

Since this Field trait requires Send and Sync, I assume that the FieldRepresentingType type needs to have unconditional Send and Sync impls, as opposed to inheriting the auto traits via the PhantomData field.

@theemathas
Copy link
Contributor

theemathas commented Feb 21, 2026

This code prints 4 with this PR, ignoring the possibility that the DST field might need extra padding for alignment:

#![feature(field_projections)]
#![expect(incomplete_features, dead_code)]

use std::field::{Field, field_of};

struct Thing(i32, dyn Send + Sync);

fn main() {
    let x = <field_of!(Thing, 1) as Field>::OFFSET;
    println!("{x}");
}

In contrast, offset_of!() requires the relevant field to be Sized:

#![expect(dead_code)]

use std::mem::offset_of;

struct Thing(i32, dyn Send + Sync);

fn main() {
    let x = offset_of!(Thing, 1);
    println!("{x}");
}
error[E0277]: the size for values of type `(dyn Send + Sync + 'static)` cannot be known at compilation time
 --> src\main.rs:8:13
  |
8 |     let x = offset_of!(Thing, 1);
  |             ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `(dyn Send + Sync + 'static)`
  = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0277`.

@theemathas
Copy link
Contributor

theemathas commented Feb 21, 2026

The following code ICEs with this PR, due to the FRT implementing the Field trait with Type = dyn Send + Sync, despite the fact that the Field trait implicitly requires the Type associated type to be Sized:

#![feature(field_projections)]
#![expect(incomplete_features, dead_code)]

use std::field::{Field, field_of};

struct Thing(dyn Send + Sync);

fn main() {
    foo::<field_of!(Thing, 0)>();
}

fn foo<F: Field>() {
    let _ = Box::<<F as Field>::Type>::new_uninit();
}
Error output
error: internal compiler error: compiler\rustc_monomorphize\src\collector.rs:719:50: collection encountered polymorphic constant: Unevaluated(UnevaluatedConst { def: DefId(2:2571 ~ core[80cb]::mem::SizedTypeProperties::SIZE), args: [dyn [Binder { value: AutoTrait(DefId(2:4054 ~ core[80cb]::marker::Sync)), bound_vars: [] }, Binder { value: AutoTrait(DefId(2:39350 ~ core[80cb]::marker::Send)), bound_vars: [] }] + '{erased}], promoted: None }, usize)
 --> library\alloc\src\boxed.rs:324:16


thread 'rustc' (39488) panicked at compiler\rustc_monomorphize\src\collector.rs:719:50:
Box<dyn Any>
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
   1: <rustc_hir_pretty::State as rustc_ast_pretty::pprust::state::PrintState>::print_generic_args
   2: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
   3: <rustc_errors::diagnostic::Diag<rustc_errors::diagnostic::BugAbort>>::emit
   4: <rustc_errors::DiagCtxtHandle>::span_bug::<rustc_span::span_encoding::Span, alloc::string::String>
   5: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
   6: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
   7: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
   8: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
   9: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
  10: rustc_middle::util::bug::span_bug_fmt::<rustc_span::span_encoding::Span>
  11: <rustc_monomorphize::collector::UsageMap>::get_user_items    
  12: <rustc_monomorphize::collector::MirUsedCollector as rustc_middle::mir::visit::Visitor>::visit_const_operand
  13: <rustc_monomorphize::collector::MirUsedCollector as rustc_middle::mir::visit::Visitor>::super_terminator
  14: <rustc_monomorphize::collector::MirUsedCollector as rustc_middle::mir::visit::Visitor>::visit_terminator
  15: rustc_monomorphize::collector::collect_roots
  16: rustc_query_impl::query_impl::limits::alloc_self_profile_query_strings
  17: <std::thread::local::LocalKey<rustc_data_structures::sync::worker_local::ThreadData>>::with::<<rustc_data_structures::sync::worker_local::RegistryId>::verify::{closure#0}, (rustc_data_structures::sync::worker_local::RegistryId, usize)>
  18: RINvMs2_NtNtCsjk4If7qqH0b_3std6thread5localINtB6_8LocalKeyINtNtCs3ss6HBggOLS_4core4cell4CellPuEE4withNCINvNtNtNtCslGuD12ebP0h_12rustc_middle2ty7context3tls13enter_contextNCNCINvMs1_NtNtB1M_9dep_graph5graphNtB2T_12DepGraphData9with_taskTNtNtCsb06bXvORIT1_16      
  19: RINvNtCslGuD12ebP0h_12rustc_middle9dep_graph9with_depsNCNCINvMs1_NtB2_5graphNtB11_12DepGraphData9with_taskTNtNtCsb06bXvORIT1_16rustc_query_impl8plumbing9QueryCtxtINtB1L_26SemiDynamicQueryDispatcherINtNtNtB4_5query6caches12DefaultCacheTNtNtNtB4_2ty8instance      
  20: RINvMs2_NtNtCsjk4If7qqH0b_3std6thread5localINtB6_8LocalKeyINtNtCs3ss6HBggOLS_4core4cell4CellPuEE4withNCINvNtNtNtCslGuD12ebP0h_12rustc_middle2ty7context3tls13enter_contextNCINvNtCsb06bXvORIT1_16rustc_query_impl9execution16execute_job_incrINtNtNtB1M_5query6c      
  21: RINvNtCsb06bXvORIT1_16rustc_query_impl9execution17try_execute_queryINtNtNtCslGuD12ebP0h_12rustc_middle5query6caches12DefaultCacheTNtNtNtB1a_2ty8instance8InstanceNtNtNtB1a_3mir4mono14CollectionModeEINtNtB18_5erase10ErasedDataAhj20_EEKVNtB4_10QueryFlagsS7is_      
  22: rustc_monomorphize::collector::collect_roots
  23: rustc_monomorphize::collector::collect_roots
  24: rustc_monomorphize::collector::collect_roots
  25: rustc_monomorphize::collector::collect_items_root
  26: RINvMNtNtCshA4wA9hNRNN_21rustc_data_structures4sync8parallelNtB3_13ParallelGuard3runuNCNCNCINvB3_15par_for_each_inNtNtNtCslGuD12ebP0h_12rustc_middle3mir4mono8MonoItemINtNtCs9dkY0A6RMMU_5alloc3vec3VecB1O_ENCNCNvNtCsaQMz2UQdcge_18rustc_monomorphize9collector      
  27: RINvXs4_NtNtCs9dkY0A6RMMU_5alloc3vec9into_iterINtB6_8IntoIterNtNtNtCslGuD12ebP0h_12rustc_middle3mir4mono8MonoItemENtNtNtNtCs3ss6HBggOLS_4core4iter6traits8iterator8Iterator4folduNCINvNvB1O_8for_each4callBX_NCNCINvNtNtCshA4wA9hNRNN_21rustc_data_structures4sy      
  28: rustc_data_structures::sync::parallel::par_for_each_in::<rustc_middle::mir::mono::MonoItem, alloc::vec::Vec<rustc_middle::mir::mono::MonoItem>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}::{closure#0}>
  29: <rustc_session::session::Session>::time::<(), rustc_monomorphize::collector::collect_crate_mono_items::{closure#1}>
  30: rustc_monomorphize::collector::collect_crate_mono_items      
  31: rustc_monomorphize::partitioning::compute_codegen_unit_name 
  32: <std::thread::local::LocalKey<rustc_data_structures::sync::worker_local::ThreadData>>::with::<<rustc_data_structures::sync::worker_local::RegistryId>::verify::{closure#0}, (rustc_data_structures::sync::worker_local::RegistryId, usize)>
  33: RINvMs2_NtNtCsjk4If7qqH0b_3std6thread5localINtB6_8LocalKeyINtNtCs3ss6HBggOLS_4core4cell4CellPuEE4withNCINvNtNtNtCslGuD12ebP0h_12rustc_middle2ty7context3tls13enter_contextNCNCINvMs1_NtNtB1M_9dep_graph5graphNtB2T_12DepGraphData9with_taskTNtNtCsb06bXvORIT1_16      
  34: RINvNtCslGuD12ebP0h_12rustc_middle9dep_graph9with_depsNCNCINvMs1_NtB2_5graphNtB11_12DepGraphData9with_taskTNtNtCsb06bXvORIT1_16rustc_query_impl8plumbing9QueryCtxtINtB1L_26SemiDynamicQueryDispatcherINtNtNtB4_5query6caches11SingleCacheINtNtB3e_5erase10Erased      
  35: RINvMs2_NtNtCsjk4If7qqH0b_3std6thread5localINtB6_8LocalKeyINtNtCs3ss6HBggOLS_4core4cell4CellPuEE4withNCINvNtNtNtCslGuD12ebP0h_12rustc_middle2ty7context3tls13enter_contextNCINvNtCsb06bXvORIT1_16rustc_query_impl9execution16execute_job_incrINtNtNtB1M_5query6c      
  36: rustc_query_impl::execution::try_execute_query::<rustc_middle::query::caches::SingleCache<rustc_middle::query::erase::ErasedData<[u8; 24]>>, {rustc_query_impl::QueryFlags { is_anon: false, is_depth_limit: false, is_feedable: false }}, true>
  37: rustc_codegen_ssa::base::codegen_crate::<rustc_codegen_llvm::LlvmCodegenBackend>
  38: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  39: <rustc_session::session::Session>::time::<alloc::boxed::Box<dyn core::any::Any>, rustc_interface::passes::start_codegen::{closure#0}>
  40: rustc_interface::passes::start_codegen
  41: <rustc_interface::queries::Linker>::codegen_and_build_linker 
  42: RINvMs2_NtNtCsjk4If7qqH0b_3std6thread5localINtB6_8LocalKeyINtNtCs3ss6HBggOLS_4core4cell4CellPuEE4withNCINvNtNtNtCslGuD12ebP0h_12rustc_middle2ty7context3tls13enter_contextNCINvMsh_B1I_NtB1I_10GlobalCtxt5enterNCNCINvNtCsgDCgBVpkTu4_15rustc_interface6passes28      
  43: RINvMsl_NtNtCslGuD12ebP0h_12rustc_middle2ty7contextNtB6_6TyCtxt18create_global_ctxtINtNtCs3ss6HBggOLS_4core6option6OptionNtNtCsgDCgBVpkTu4_15rustc_interface7queries6LinkerENCNCINvNtB1Z_6passes28create_and_enter_global_ctxtB1j_NCNCNvCslx5e3yw6wJm_17rustc_dr      
  44: rustc_interface::passes::create_and_enter_global_ctxt::<(), rustc_driver_impl::run_compiler::{closure#0}::{closure#1}>
  45: RNvXst_NtCs9dkY0A6RMMU_5alloc5boxedINtB5_3BoxDG_INtNtNtCs3ss6HBggOLS_4core3ops8function6FnOnceTRL0_NtNtCsefPgroWLkb7_13rustc_session7session7SessionNtNtNtCslGuD12ebP0h_12rustc_middle2ty7context10CurrentGcxINtNtB7_4sync3ArcNtNtCshA4wA9hNRNN_21rustc_data_str      
  46: rustc_interface::passes::create_and_enter_global_ctxt::<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure#2}>
  47: RINvMs_Csl9ikBPEYqOJ_10scoped_tlsINtB5_9ScopedKeyNtCslMKAykjEFI3_10rustc_span14SessionGlobalsE3setNCNCNCINvNtCsgDCgBVpkTu4_15rustc_interface4util26run_in_thread_with_globalsNCINvB1H_31run_in_thread_pool_with_globalsNCINvNtB1J_9interface12run_compileruNCNvC      
  48: RINvCslMKAykjEFI3_10rustc_span27create_session_globals_thenuNCNCNCINvNtCsgDCgBVpkTu4_15rustc_interface4util26run_in_thread_with_globalsNCINvB15_31run_in_thread_pool_with_globalsNCINvNtB17_9interface12run_compileruNCNvCslx5e3yw6wJm_17rustc_driver_impl12run_      
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly 

note: please attach the file at `C:\Users\theem\Documents\foo\rustc-ice-2026-02-21T05_04_36-36980.txt` to your bug report

note: rustc 1.95.0-dev running on x86_64-pc-windows-msvc

note: compiler flags: --crate-type bin -C embed-bitcode=no -C debuginfo=2 -C incremental=[REDACTED]

note: some of the compiler flags provided by cargo are hidden      

query stack during panic:
#0 [items_of_instance] collecting items used by `alloc::boxed::Box::<dyn core::marker::Send + core::marker::Sync>::new_uninit`        
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
error: could not compile `foo` (bin "foo")

@theemathas theemathas added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 21, 2026
@rust-bors

This comment has been minimized.

@theemathas
Copy link
Contributor

theemathas commented Feb 22, 2026

Field-representing types can cause privacy violations. See the following code:

dep/src/lib.rs

#![feature(field_projections)]
#![expect(incomplete_features)]

use std::field::field_of;

struct Inner;

pub struct Outer(Inner);

pub type MyField = field_of!(Outer, 0);

pub trait GetUnreachable {
    type Assoc;
}

mod m {
    pub struct Unreachable;

    impl Unreachable {
        #[expect(dead_code)]
        pub fn method() {}
    }

    impl crate::GetUnreachable for crate::Inner {
        type Assoc = Unreachable;
    }
}

src/main.rs

#![feature(field_projections)]
#![expect(incomplete_features)]

use std::field::Field;

use dep::{GetUnreachable, MyField};

fn main() {
    <MyField as Access>::AccessAssoc::method();
}

trait Access {
    type AccessAssoc;
}

impl<T: Field<Type: GetUnreachable>> Access for T {
    type AccessAssoc = <T::Type as GetUnreachable>::Assoc;
}

Error output when compiling this code with this PR:

error: missing optimized MIR for `dep::m::Unreachable::method` in the crate `dep`
   |
note: missing optimized MIR for this item (was the crate `dep` compiled with `--emit=metadata`?)
  --> dep\src\lib.rs:21:9
   |
21 |         pub fn method() {}
   |         ^^^^^^^^^^^^^^^

error: could not compile `foo` (bin "foo") due to 1 previous error

See also #151284

I'm guessing that FieldRepresentingType needs to have an additional generic parameter for the field's type, not just for the containing struct's type.

@oli-obk
Copy link
Contributor

oli-obk commented Feb 22, 2026

I'm guessing that FieldRepresentingType needs to have an additional generic parameter for the field's type, not just for the containing struct's type.

That, or reachability needs to process FRTs similar to projections and look at more than just the types in the generic args. That's an annoying complication though, so adding the field type directly to the frt is the least invasive scheme

@theemathas
Copy link
Contributor

theemathas commented Feb 23, 2026

Actually... there's another side effect of adding a second type parameter for FieldRepresentingType: It changes the orphan rules. For example:

dep/src/lib.rs:

pub struct Outer<T>(pub T);
pub trait Trait {}

src/lib.rs:

#![feature(field_projections)]
#![expect(incomplete_features)]
use std::field::field_of;
use dep::{Outer, Trait};

struct Inner;
impl Trait for field_of!(Outer<Inner>, 0) {}

This code currently doesn't compile with the PR, producing the following error:

error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
  --> src\lib.rs:10:1
   |
10 | impl Trait for field_of!(Outer<Inner>, 0) {}
   | ^^^^^^^^^^^^^^^--------------------------
   |                |
   |                `Outer` is not defined in the current crate
   |
   = note: impl doesn't have any local type before any uncovered type parameters
   = note: for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
   = note: define and implement a trait or new type instead

For more information about this error, try `rustc --explain E0117`.

However, I believe that it will compile if FieldRepresentingType were to gain a second type parameter (since impl ForeignTrait for Box<ForeignType, LocalType> {} is legal).

This seems undesirable, since now dep adding impl<T> Trait for field_of!(Outer<T>, 0) {} is a breaking change...

@oli-obk
Copy link
Contributor

oli-obk commented Feb 23, 2026

We can land this PR as is and do a follow-up for the privacy issue as there may be multiple ways to go about it and none of them really require major divergence from this PR

So to land:

  • add a test for the ICE
  • add an unchecked box entry to things to do before stabilization in the tracking issue

@theemathas
Copy link
Contributor

theemathas commented Feb 23, 2026

I think the Send/Sync issue and the DST issue seem not too hard to fix, so maybe those could also be fixed in this PR before merging if that's not too much trouble?

@BennoLossin BennoLossin force-pushed the field-projections-lang-item branch from e7bae32 to 8c1da56 Compare February 23, 2026 21:03
@rustbot
Copy link
Collaborator

rustbot commented Feb 23, 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.

@BennoLossin
Copy link
Contributor Author

I think the Send/Sync issue and the DST issue seem not too hard to fix, so maybe those could also be fixed in this PR before merging if that's not too much trouble?

I think so too. I fixed the send/sync thing as well as @fmease's suggestions now. I'll take a look at the DST fixes tomorrow. Thanks a lot for taking a look @theemathas!

@rust-log-analyzer
Copy link
Collaborator

The job pr-check-2 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
REPOSITORY                                   TAG       IMAGE ID       CREATED       SIZE
ghcr.io/dependabot/dependabot-updater-core   latest    b72a662c47e3   3 weeks ago   790MB
=> Removing docker images...
Deleted Images:
untagged: ghcr.io/dependabot/dependabot-updater-core:latest
untagged: ghcr.io/dependabot/dependabot-updater-core@sha256:57ef9cc45f72cc4258ee1baa8243bc3cd55c0a0e570b6768c37346247be35f0d
deleted: sha256:b72a662c47e31df2e7bf59368b2b83be239f02a1baa721393717711a1a719df9
deleted: sha256:3e13ccd80f19769f39008cfc6549938e1ea4905f47b028c1df2dd6085191386c
deleted: sha256:842807995a512b2c5a9b241a3aecdbe79af6b0642d96fa5460cfcf0c9d8be295
deleted: sha256:0f9074b9f46f4570eb7cb4b65fcb3c3d909f9b1d14ca66b30508117b6deda303
deleted: sha256:2ca99cb9251d19157c56b5d91c8961bb4b35196a5ca9b4ffdccbf24abbfe2a5f
---
[RUSTC-TIMING] build_helper test:false 0.398
[RUSTC-TIMING] object test:false 1.888
[RUSTC-TIMING] serde_derive test:false 3.618

thread 'rustc' (33874) panicked at compiler/rustc_span/src/symbol.rs:2696:13:
duplicate symbols in the rustc symbol list and the extra symbols added by the driver: ["field"]
stack backtrace:
   0: __rustc::rust_begin_unwind
   1: core::panicking::panic_fmt
   2: <rustc_span::symbol::Interner>::with_extra_symbols
   3: <rustc_span::SessionGlobals>::new
---
warning: the ICE couldn't be written to `/checkout/rustc-ice-2026-02-23T21_31_55-33873.txt`: Read-only file system (os error 30)

note: rustc 1.95.0-nightly (a8bbe8384 2026-02-23) running on x86_64-unknown-linux-gnu

note: compiler flags: --crate-type lib -C opt-level=3 -C embed-bitcode=no -C debug-assertions=on -C symbol-mangling-version=v0 -Z annotate-moves -Z unstable-options -Z force-unstable-if-unmarked -Z macro-backtrace -C split-debuginfo=off -C link-args=-Wl,-z,origin -C link-args=-Wl,-rpath,$ORIGIN/../lib -Z unstable-options -Z binary-dep-depinfo -Z on-broken-pipe=kill -Z tls-model=initial-exec -Z allow-features=binary-dep-depinfo,proc_macro_span,proc_macro_span_shrink,proc_macro_diagnostic

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack
note: Clippy version: clippy 0.1.95 (a8bbe83849 2026-02-23)

[RUSTC-TIMING] bootstrap test:false 0.033
error: could not compile `bootstrap` (lib)

Caused by:
  process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc /checkout/obj/build/x86_64-unknown-linux-gnu/stage1/bin/clippy-driver /checkout/obj/build/bootstrap/debug/rustc --crate-name bootstrap --edition=2024 src/bootstrap/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --crate-type lib --emit=dep-info,metadata -C opt-level=3 -C embed-bitcode=no -C debug-assertions=on --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("build-metrics", "tracing"))' -C metadata=4ad42254cba96222 -C extra-filename=-c1ba44e6f82c344d --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps --target x86_64-unknown-linux-gnu -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/release/deps --extern build_helper=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libbuild_helper-1a165ff0512d388b.rmeta --extern cc=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libcc-e8b72389f570f612.rmeta --extern clap=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libclap-528e788dbac2c097.rmeta --extern clap_complete=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libclap_complete-879aece6f3e63dae.rmeta --extern cmake=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libcmake-07b9bb9be6b1b074.rmeta --extern home=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libhome-2f507f561cff0681.rmeta --extern ignore=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libignore-046bb9473759862e.rmeta --extern libc=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/liblibc-5a0def22296216ef.rmeta --extern object=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libobject-ce8c80c20f419a4a.rmeta --extern opener=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libopener-d964e808b230f9ae.rmeta --extern semver=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libsemver-b0d24b084e33e6f1.rmeta --extern serde=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libserde-701badf175383512.rmeta --extern serde_derive=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/release/deps/libserde_derive-1fa03a82fecc185b.so --extern serde_json=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libserde_json-eead5493d3589775.rmeta --extern sha2=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libsha2-73534e554d88bc7c.rmeta --extern tar=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libtar-09cc887f3dc80620.rmeta --extern termcolor=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libtermcolor-dded6b4eadf49edb.rmeta --extern toml=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libtoml-cd85b483e0710f2a.rmeta --extern walkdir=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libwalkdir-3c4a8936f1d238be.rmeta --extern xz2=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/deps/libxz2-a4e500b70e41fd69.rmeta --sysroot /checkout/obj/build/x86_64-unknown-linux-gnu/stage1 --cfg=windows_raw_dylib -Csymbol-mangling-version=v0 -Zannotate-moves -Zunstable-options -Zforce-unstable-if-unmarked -Zmacro-backtrace -Csplit-debuginfo=off -Clink-args=-Wl,-z,origin '-Clink-args=-Wl,-rpath,$ORIGIN/../lib' -Zunstable-options -Z binary-dep-depinfo -L native=/checkout/obj/build/x86_64-unknown-linux-gnu/stage2-tools/x86_64-unknown-linux-gnu/release/build/lzma-sys-535b805d2d1fdea1/out` (exit status: 101)
Bootstrap failed while executing `clippy ci --stage 2`
Build completed unsuccessfully in 0:04:39
  local time: Mon Feb 23 21:31:55 UTC 2026
  network time: Mon, 23 Feb 2026 21:31:55 GMT
##[error]Process completed with exit code 1.

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 I-types-nominated Nominated for discussion during a types team meeting. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. 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.

7 participants