Skip to content

Add try_into_boxed (and potentially into_boxed_inner) for Rc<T>/Arc<T> where T: ?Sized #269

Closed as not planned
@Kolsky

Description

@Kolsky

Proposal

Problem statement

Currently there is no stable way to convert Rc/Arc<dyn Trait> to Box<dyn Trait> even though Box -> Rc/Arc is covered by a From implementation, and both into_inner/try_unwrap are there as well. Even a manual nightly solution has a lot of soundness footguns.

Motivating examples or use cases

A lot of UI-oriented API's use Arcs for widget trees (an example being druid). They might be able to benefit from having object-safe methods taking Box<Self> during tree updates. Any pattern where bulk multithreaded operations happen on Arcs happen to have synchronous execution inbetween should be a good fit for conversions of this sort.
Even when T: Sized, an extra cost of moving the value is associated with unwrapping then boxing, which can be a detriment for big data structures (the case with arrays can usually be solved by cloning to Vec before resorting to TryFrom).

Solution sketch

I propose adding a private function

impl<T: ?Sized> Box<T> {
    unsafe fn read_unsized(ptr: *const T) -> Self;
}

mirroring pointer API, and then closely following implementation of try_unwrap, with the replacement of ptr::read by Box::read_unsized.

Alternatives

There is a crate called rc-box made by CAD97 with over 100'000 downloads. Overall it's a better solution for modifying uniquely owned Arc without resorting to calling get_mut each time (+more typesafe), and, unlike Arc -> Box, it avoids reallocation. However, it's not object safe, and it can only produce semantics of into_boxed_inner (otherwise DerefMut would be unsound).

Implementing the conversion manually has to resort to a nightly feature ptr_metadata and is very dangerous just for into_inner_boxed.

Links and related work

An old URLO thread

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