Open
Description
Proposal
Problem statement
For Rc/Arc, returns the Some(this)
, if the has exactly one strong reference.
Motivating examples or use cases
I created a UniqArc wrapper that allows unique Arc to be DerefMut like a Box,
But I can't stably convert some shared Arc into a UniqArc, similar Arc::try_unwrap(this).ok()
For the sized type, Arc::new(Arc::into_inner(this)?)
can be used, but this requires reallocating an Arc,
And if it's an unsized type, I have no way at all
// If there is such a method:
// pub fn into_unique(this: Arc<T>) -> Option<Arc<T>> { ... }
// I can create:
impl<T: ?Sized> UniqArc<T> {
pub fn consume_new(arc: Arc<T>) -> Option<Self> {
let unique = Arc::into_unique(arc)?;
Some(UniqArc(unique))
}
}
Solution sketch
- Return
None
when there are other strong references - Return
Some(this)
when there are no other strong references and no other weak references - Dissociate weak references and return
Some(this)
when there are no other strong references but weak references
Partial implementation:
impl<T: ?Sized> Arc<T> {
#[inline]
pub fn into_unique(this: Self) -> Option<Self> {
if this.inner().strong.fetch_sub(1, Release) != 1 {
return;
}
// If there are outstanding weak references, it will be dissociated like make_mut
todo!();
this.inner().strong.fetch_add(1, Relaxed);
Some(this)
}
}
Alternatives
-
What other designs have been considered and what is the rationale for not choosing them?
- If
Option<Weak<T>>
is returned, additional upgrade costs will be required - If
Option<*const T>
is returned, it can easily lead to unnecessary unsafe code
- If
-
What is the impact of not doing this?
- Unable to mutable on the last Arc instance stably without copying
-
If this is a language proposal, could this be done in a library or macro instead?
- The public methods of Rc/Arc seems insufficient to accomplish this