I have been thinking about the relationship between the proposed Reborrow work and the recent Share/cheap-clone ideas.
I think there may be a useful common abstraction above them:
unsafe auto trait Alias {}
trait Share: Alias {}
trait Reborrow: Alias {}
The basic idea is that Alias means:
Another handle to the same logical resource can be created without transferring ownership of that resource away from the original value.
Share and Reborrow are then two different aliasing disciplines.
For a shared alias:
Arc<T>: Share
creating another alias simply produces another independent handle to the same underlying resource, and the original remains fully usable.
For a reborrowed alias:
&mut T: Reborrow
creating another alias produces a temporary view of the same resource, but the original is logically restricted for the duration of the alias, according to the usual borrowing rules.
So conceptually:
Alias
/ \
Share Reborrow
Consider:
struct X<'a, T, C> {
a: Option<&'a mut T>, // Reborrow -> Alias
b: Arc<C>, // Share -> Alias
}
Here, a participates in reborrowing, while b participates in sharing.
A temporary alias of X is not something you manually construct by rewriting fields. Instead, it is simply a derived view of X that the compiler can form when needed, where:
ais reborrowed automatically (if accessed mutably)bis shared (cheaply cloned or reference-counted)
So conceptually, the compiler treats aliasing X as producing a new view:
X (aliased view)
{
a: reborrowed view of x.a,
b: shared view of x.b,
}
Copy fields and metadata
I do not think ordinary Copy fields should automatically imply Alias.
Consider:
struct X<'a, T> {
a: &'a mut T,
has_been_modified: bool,
}
If aliasing X simply copies the bool, then two aliases could diverge:
- one alias mutates
aand setshas_been_modified = true - another alias still sees
false
Now the two handles disagree about state that is meant to describe the same logical resource.
The compiler cannot know whether a Copy field is:
- harmless metadata (
len,capacity, etc.) - or logically significant state tied to the resource
So the safe default must be conservative:
struct automatically implements Alias
iff every field implements Alias
Copy alone is not sufficient evidence of alias-safety.
Safe opt-in for metadata-heavy types
Types that intentionally include duplicated metadata can opt in manually:
struct SliceMut<'a, T> {
a: &'a mut T, // Reborrow, therefore Alias
len: usize, // Copy, therefore !Alias
}
unsafe impl<T> Alias for SliceMut<'_, T> {}
Here, len is just descriptive metadata, so copying it as part of an alias is fine. The unsafe impl is the author's promise that doing so cannot break the type's invariants.
But not every handle-like type should be able to opt in this way.
For example, MutexGuard<'_, T> carries the responsibility of unlocking the mutex when it is dropped. Creating another guard would duplicate that responsibility, so it should not be Alias.
Roughly:
SliceMut<'_, T> -> explicit Alias is reasonable
Arc<Mutex<T>> -> Share -> Alias
&mut T -> Reborrow -> Alias
MutexGuard<'_, T> -> !Alias
So Alias is not simply "this type refers to something". It means another alias can be created without breaking the rules or responsibilities of the original value.
How this would look in practice
Shared case (Share)
fn use_shared<T: Share>(x: T) {
foo(x); // x.share()
boo(x); // x.share()
}
Both aliases are independent and fully usable.
Reborrow case (Reborrow with auto-reborrowing)
fn use_reborrow<'a, T>(x: Option<&'a mut T>) {
foo(x); // compiler may implicitly reborrow
boo(x); // reborrow rules ensure safety
}
Here, the user does not manually construct aliases. The compiler inserts reborrows as needed, and ensures that all derived uses respect exclusivity.
Mixed struct case (Alias composition)
struct X<'a, T, C> {
a: Option<&'a mut T>,
b: Arc<C>,
}
fn process<'a, T, C>(x: X<'a, T, C>) {
foo(x);
boo(x);
}
Conceptually:
ais reborrowed automatically when neededbis shared viaArc
The important point is that the whole struct can be treated as an Alias, even though its fields use different aliasing disciplines.
Mutex example
fn use_mutex<T>(m: Arc<Mutex<T>>) {
foo(m); // Share
boo(m); // Share
}
Here Arc<Mutex<T>> is Share, hence Alias.
But:
fn use_guard<T>(g: MutexGuard<'_, T>) {
foo(g);
boo(g); // invalid: would duplicate unlock responsibility
}
MutexGuard is not Alias, because aliasing it would duplicate ownership of the unlock action.
However, the inner &mut T remains a valid Reborrow.
Closing thought
I am curious whether this has already been explored as an explicit trait relationship.
In particular, could Alias be useful as a compiler-known auto trait that:
- composes structurally across
ShareandReborrow - is automatically derived when all fields are
Alias - requires explicit
unsafeopt-in when a type includes duplicated metadata that is not itselfAlias
It feels like this might be a unifying abstraction over several existing and proposed ownership mechanisms.