If you've ever used Box<T> or Pin<&mut T> or MaybeUninit<T>, you've hit this wall: you know the wrapped type has a field, but you can't reach it through the wrapper.
struct Person {
name: String,
age: u32,
}
fn greet(p: Pin<&mut Person>) {
// This doesn't work:
// p.name = String::from("Alice");
// You have to do this instead:
Person::name.set(p.as_mut().get_mut(), String::from("Alice"));
}
That's ugly. That's pin-project ugly. And it's about to change.
The Problem Field Projection Solves
Rust has a rich ecosystem of wrapper types:
- Smart pointers:
Box<T>,Rc<T>,Arc<T> - Interior mutability:
Cell<T>,RefCell<T>,UnsafeCell<T> - Pinning:
Pin<&mut T> - Uninitialized:
MaybeUninit<T> - Custom:
NonNull<T>,VolatilePtr<T>(embedded),RcuMutex<T>(Linux kernel)
All of these wrap a T and all of them should let you access fields of T naturally. But they can't, because field access in Rust goes through the type's inherent impl — and these wrappers don't have inherent impls for the wrapped type's fields.
The status quo: manually implement Deref (if possible) or use procedural macros like pin-project, field-access, or owning-ref.
Field projection is a native language feature that says: "When I access a field through this wrapper type, give me the right kind of borrow."
What It Looks Like (Hypothetical)
The RFC is still being designed, but the vision looks something like:
struct Wrapper {
inner: Inner,
metadata: Metadata,
}
struct Inner {
name: String,
}
// With field projection, you could do:
fn process(w: Pin<&mut Wrapper>) {
// Borrow type changes based on the wrapper's semantics
w.inner.name = String::from("Alice"); // gets &mut String through Pin
w.metadata = Metadata::default(); // gets &mut Metadata
}
The key insight: different wrapper types have different borrow semantics. Pin<&mut T> preserves mutability but prevents reborrowing. Cell<T> gives &T that you can only mutate via .set(). Field projection would let each wrapper type declare: "When you access field F through me, here's what you get."
Why This Matters Now
This is a 2025H2 project goal — a priority for the Rust language team targeting 2026/2027 stabilization. The timeline:
- Now: Design meetings and RFC refinement
- Goal: Land as a lang experiment on nightly within 2026
- Target: Stabilization in a 2026 or 2027 release
This isn't a fringe feature. It's happening because:
- The Linux kernel uses Rust with heavy pinning and custom pointer types. They need this daily.
- Embedded systems have volatile pointers, reference-counted handles, custom allocators — all of which need field access.
- The ecosystem has spoken — crates like
pin-projecthave 50M+ downloads because the pain is real.
The Design Challenge
Here's why it's taken years: the design has to handle multiple cases elegantly:
| Wrapper | Field Borrow Type | How it works |
|---------|-------------------|--------------|
| Box<T> | &T / &mut T | Standard ownership semantics |
| Pin<&mut T> | Pin<&mut Field> | Preserves pinning invariant |
| Cell<T> | &Cell<Field> | Interior mutability only |
| MaybeUninit<T> | &mut MaybeUninit<Field> | Uninitialized-aware |
| NonNull<T> | NonNull<Field> | Raw pointer semantics |
The RFC explores two approaches:
- Projection traits — a trait system where wrappers declare their field semantics
- Inherent projection blocks — syntax on the wrapper type itself
The teams are still debating which path, but both lead to the same destination: native field access through wrappers.
Why You Should Care
If you write library code with generics over smart pointers, you need this. If you maintain pin-project or similar crates, your users will soon have a language-native alternative. If you write embedded Rust or kernel code, this reduces boilerplate significantly.
But more broadly: this is Rust getting serious about being a practical systems language. The "zero-cost abstraction" promise now extends to custom pointer types. You can design your own smart pointer with proper field access — no macro magic required.
The Road Ahead
Track the progress at the Rust Project Goals repo. The lang team is holding design meetings through Q1 2026, with an RFC update expected by mid-year.
If you want to influence the design, the Zulip channel is #t-lang/field-projections. The champions are Benno Lossin and Tyler Mandry.
This is one of those features that won't make headlines but will quietly make Rust code better every day. The wrappers we've lived with for years — they're about to get a proper native solution.