Skip to content

Add into_unique method to Rc and Arc #608

Open
@A4-Tacks

Description

@A4-Tacks

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
  • 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

Links and related work

unique-rc

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions