Description
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 Arc
s 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 Arc
s 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
.