rust-lang / rust-lang/libs-team

Add `into_unique` method to `Rc` and `Arc`

Open
#608 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

ACP-accepted api-change-proposal
Dominant language
Rust
Stars
178
Forks
28
Avg merge
15m
Merged PRs (30d)
1

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by comparing the existing Rc and Arc APIs, especially Arc::try_unwrap, Arc::into_inner, and make_mut, and review the unique-rc crate linked in the issue. Resolve the ownership and weak-reference behavior for both types, including unsized values, then document the accepted design and add coverage for the proposed Some/None outcomes.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.