Rust team's 'Beyond the &' prototype would give smart pointers reference powers

Rust has many kinds of smart pointers, in the standard library and in user code, yet some things that work with built-in references do not work with them. Tyler Mandry, lead of the Rust project's language team, spoke at RustConf 2026 about the long effort to close that gap under the project name 'Beyond the &'. LWN reports on the talk. Mandry said he has worked on the problem all through 2026, alongside several other interested members of the language team.

He opened with a concrete failure. A simplified program renders content and caches it in a hash map, using the map-entry API's or_insert_with(), which takes a callback to fill an empty entry. With shared state held through a built-in &mut RenderState, it compiles, because the borrow checker can see that state.cache and state.template are separate fields and can be used at the same time. Wrap the state in a Mutex so threads can share it, and the borrow checker rejects the program. It now sees only opaque accesses to a MutexGuard, cannot tell the accesses are disjoint, and has to assume the mutable borrow might edit the state while the callback reads it, a potential data race. The workaround is to dereference the guard once and reborrow: let state: &mut RenderState = &mut *state.lock().unwrap(). That builds a built-in reference again, so the check passes, but Mandry said it is not intuitive and that complexity like this adds to Rust's steep learning curve.

Pointer types are everywhere, he continued, and each has slightly different semantics: raw pointers cannot be safely dereferenced, and MaybeUninit can be written to but not read from. That versatility makes a single design hard.

The team's solution, based on the work of Nadrieril and Benno Lossin, is to expose the compiler's internal notion of a 'place' to user code. A place is Rust's equivalent of C's lvalues: a location values can be read from or written to. It is an abstract expression that exists at compile time, such as state.cache, while a pointer is one way to represent a place at run time. Each smart pointer would get a new handle type, often just a wrapper around an unsafe pointer to the same location. The compiler would create handles automatically for the places a program refers to, and user code would implement traits on handle types to control how the borrow checker treats them. That offers more flexibility than the existing Deref and DerefMut traits.

Mandry showed several traits. WritePlace tells the borrow checker a handle can be written to, and how. His example was a handle around a NonNull pointer: with SAFE set to false the write is treated as an unsafe operation, the write is forwarded to the wrapped raw pointer, and the whole implementation is marked unsafe because a wrong one could make the borrow checker err and cause unsound behavior. ReadPlace does the same for reads. ProjectPlace tells the borrow checker how to turn a place holding a structure into a place holding one of its fields, for instance turning the handle for a MutexGuard into one for a MutexGuard when the programmer writes state.template. BorrowPlace tells it how to create a new smart pointer that borrows a place, the way & does for built-in references.

The syntax for making a new smart pointer with BorrowPlace is undecided. Reusing & could confuse readers and hurt type inference; @ is one proposal, but people are not entirely happy with it. BorrowPlace carries everything the borrow checker needs, so built-in behavior can be expressed through the same mechanism. Mandry showed an implementation for &T that marks access as shared, ties the borrow to lifetime 'a, and declares borrowing safe. That would serve as a model for authors of reference-like smart pointers and let standard library maintainers document existing counterintuitive built-in behavior. With a similar handle type for MutexGuard, the render_page() example compiles without errors; Mandry called it 'a small code change for this example, but a big semantic shift.'

There is a further benefit. Today, pattern matching works on a value behind a reference but not on one behind a smart pointer, unless you dereference and reborrow. The details exposed by BorrowPlace would be enough for the compiler to implement those matches safely.

Mandry said the language team looks for composability in new features, meaning how well a feature fits the language's existing structures and combines with others. Handles and places, he said, 'compose beautifully' because they only expose details of how the compiler already understands the language.

Still, exposing places and handles to library code is a prototype. Mandry asked the audience to read the design documentation and add examples of smart pointers with odd semantics. The next piece to flesh out is errors and diagnostics: ideally users should never see errors that mention the new traits, which would stay internal, with messages explaining the problem directly as they do for built-in references. Much work remains before it can become a stable part of the language, but Mandry is optimistic.

In Q&A, one audience member asked about destructive pattern matching, which takes ownership of a value while matching it. Mandry said it would be supported if the developer implements a VariantPlace trait for the handle, and that there are six to eight operations to implement to support every operation on a handle type, VariantPlace being one. Another asked whether the design would work for enumerations in general. After a pause, Mandry answered with a hesitant yes, then elaborated: projecting a field from an enumeration in general will probably not be possible, though there has been some exploratory work. Should it be possible to project a field from inside an Option to get an Option of the field value? 'I don't know the answer, but it's an interesting question,' he said, just as the session ran out of time.

Key facts

  • Tyler Mandry, lead of the Rust project's language team, presented 'Beyond the &' at RustConf 2026; he says he has worked on it all through 2026 with other language team members.
  • The approach exposes the compiler's internal notion of a 'place' to library code through a new handle type per smart pointer, with traits such as WritePlace, ReadPlace, ProjectPlace and BorrowPlace.
  • The motivating case: wrapping shared state in a Mutex makes the borrow checker reject code that works with &mut, and the fix today is to deref and reborrow; with a MutexGuard handle type the original code compiles.
  • It is still a prototype: the syntax for BorrowPlace borrows is undecided (@ is one proposal), and errors and diagnostics are the next part to design.
  • Per Mandry, destructive pattern matching would work with a VariantPlace trait, but projecting a field from an enumeration in general will probably not be possible.

Why it matters

Smart pointers such as MutexGuard cannot do everything built-in references can, and the gap shows up as borrow checker errors that need non-obvious workarounds. Mandry said such complexity adds to Rust's difficult learning curve. The language team says the design it has reached should allow a substantially simpler mental model of how pointers and references work. Because BorrowPlace can also describe the built-in &T, one mechanism would cover both built-in and user-defined pointers, and the standard library would gain a place to document counterintuitive built-in behavior.

Who it affects

Library authors who write smart pointers or other wrapper types are the main audience: they would implement traits on handle types to teach the borrow checker how their pointer reads, writes, projects fields and borrows. Everyday Rust programmers who use types like MutexGuard would be affected indirectly, since code like the mutex example would compile without the deref-and-reborrow workaround. Pattern matching on a value behind a smart pointer would also become possible.

How to use it

It cannot be used as a stable feature yet. Mandry asked the audience to read the design documentation, add their own examples of smart pointers with weird semantics, and try the design on abstractions they want more deeply integrated into the language, reporting any roadblocks to the team. The source gives no release version or timeline.

How solid is it

This is LWN's report of a conference talk, and the design details come from Mandry's presentation. The source describes exposing places and handles to library code as a prototype, with much more work needed before it can become a stable part of the language. The BorrowPlace syntax is undecided, and diagnostics are still to be designed. The source gives no performance or compile-time measurements, and no RFC number, tracking issue or link to the design documentation. The design builds on the work of Nadrieril and Benno Lossin.

Risks and caveats

Open questions remain. Projecting a field from an enumeration in general will probably not be possible, and Mandry said he did not know the answer to whether a field could be projected from inside an Option to yield an Option of the field. Trait implementations are unsafe because an incorrect one could make the borrow checker err and cause unsound behavior. The new traits are meant to stay hidden from users' error messages, but that part of the design is not yet worked out. The article does not say whether the design would replace Deref and DerefMut, only that handles offer more flexibility than them.

“My hope is that it will let libraries make Rust even more powerful and friendly.”

— Tyler Mandry, lead of the Rust project's language team, at RustConf 2026