Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reborrow traits

Metadata
Point of contactAapo Alasuutari
StatusProposed
FlagshipBeyond the &
Tracking issuerust-lang/rust-project-goals#399
Zulip channel#t-lang/custom-refs
lang championTyler Mandry
Teamscompiler, lang
Task owners(none)

Summary

Bring the Reborrow and CoerceShared trait to nightly Rust, enabling iteration based on user feedback. Begin work on nontrivial cases where more than one lifetime is being reborrowed or coerced into shared

Motivation

Reborrowing is fundamental to Rust’s ergonomics with references. When you pass a &mut T to a function, Rust automatically reborrows it so you can use it again after the call. But this doesn’t work for user-defined types that wrap references, like Option<&mut T>, Pin<&mut T>, or custom smart pointers.

Today, users work around this with .as_deref_mut() or .reborrow() methods, but these have a critical limitation: values derived from a reborrow cannot be returned from the function that called .reborrow(). The lifetime gets constrained to the reborrow call site. True reborrowing doesn’t have this constraint.

The status quo

The 2025H2 period produced a working implementation of the Reborrow and CoerceShared traits for types with a single lifetime parameter and trivial memory layouts. The exact mechanism for expanding the implementation from trivial cases to non-trivial memory layouts and sets of reborrowed lifetimes remains an open problem.

What we propose to do about it

This year we continue iteration on the traits based on user feedback, focusing on:

  1. Gather feedback from users - Especially from reborrow crate users and the Rust for Linux project
  2. Overcome known limitations - Support types with multiple lifetime parameters where one or more of them gets reborrowed.
  3. Support non-trivial CoerceShared - Support CoerceShared operations that reorder or drop fields.
  4. Expand safety and validity checks - CoerceShared performs an implicit type transmute and must be extensively tested and validated.
  5. Prepare for RFC - Refine the draft RFC based on implementation experience.

The fundamental design philosophy remains:

  • Reborrowing is “a memory copy with added lifetime analysis” - no user code is run.
  • The traits must achieve true reborrowing where derived values can be returned from the function.
  • Performance cost must be trivial as reborrowing is performed at every coercion site.
  • Prevent abuse - CoerceShared must not slide into the realm of a generic Coerce trait.

Work items over the next year

TaskOwner(s)Notes
Land first implementation PR to nightlyAapo Alasuutari
Solicit wide feedback on the featureAapo Alasuutari
Continue experiment based on experienceAapo Alasuutari

Team asks

TeamSupport levelNotes
langMediumContinued experiment support, design feedback
compilerSmallStandard reviews for trait implementation PRs

Frequently asked questions

How does this relate to Pin ergonomics?

Pin currently has special-cased reborrow support in the compiler. Once reborrow traits are stable, Pin<&mut T> can be reimplemented using the general mechanism, removing the special case. The Pin ergonomics goal is proceeding in parallel.

Why the shift from associated type to type parameter for CoerceShared?

Originally CoerceShared had type Target to prevent multiple coercion targets (which could enable abuse as a general coercion trait). But the trait method that motivated this fear was found unnecessary, so allowing multiple targets via trait CoerceShared<Target: Copy> {} is now safe and enables more flexibility - like a collection of &muts all coercing to &s.

Why limit to single lifetime initially?

Supporting multiple lifetimes requires dealing with rmeta (Rust metadata) complexity. Focusing on single-lifetime reborrowing first lets us get the core functionality working before tackling that additional complexity.

rust-lang/rust-project-goals#399: https://github.com/rust-lang/rust-project-goals/issues/399 lang: https://github.com/rust-lang/lang-team compiler: https://github.com/rust-lang/compiler-team