Box::new_from_ref
for making a Box<T>
from a &T
where T: CloneToUninit + ?Sized
(and Rc
and Arc
)
#483
Labels
Box::new_from_ref
for making a Box<T>
from a &T
where T: CloneToUninit + ?Sized
(and Rc
and Arc
)
#483
Proposal
Problem statement
Given a
t: &T
, whereT: CloneToUninit
, it would be nice to be able to make a heap-allocated container containing a clone oft
, such asBox<T>
orRc<T>
. Currently, such conversions are only implemented ad-hoc for specific types, e.g.impl From<&str> for Box<str>
,impl<T: Clone> From<&[T]> for Arc<[T]>
, etc.Motivating examples or use cases
Consider a custom DST
MyDst
. It is possible to write aFrom<&MyDst> for Box<MyDst>
using manual allocation and unsafe code to clone fields into the new allocation, but this manual allocation would not be necessary if the standard library provided this functionality, and the user would only need to write the unsafe code to implementCloneToUninit for MyDst
to clone the fields into the new allocation.Now that
CloneToUninit
is dyn-compatible, this also applies todyn MyTrait
wheretrait MyTrait: CloneToUninit
.Additionally, since
Rc
/Arc
's heap layout is not specified, it is only possible to write aFrom<&MyDst> for Rc<MyDst>
that makes aBox<MyDst>
and goes throughFrom<Box<T>> for Rc<T>
, making an unnecessary intermediate allocation which could be avoided if a newRc<T>
could be cloned directly from a&T
Solution sketch
Add a new function
new_from_ref
toBox<T>
,Rc<T>
,Arc<T>
whereT: ?Sized + CloneToUninit
, andtry_new_from_ref
,new_from_ref_in
, andtry_new_from_ref_in
additionally underfeature(allocator_api)
.(WIP branch (
Box
and partialRc
only): https://github.com/zachs18/rust/tree/new_from_ref)Alternate bikeshed names:
clone_from_ref
,cloned_from_ref
,new_cloned
.Alternatives
The existing
From<&str> for Box<str>
(etc) impls in the stdlib could be replaced by generalimpl<T: ?Sized + CloneToUninit> From<&T> for Box<T>/Rc<T>/Arc<T>
impls. Unfortunately, this would be a breaking change, as downstream crates can currently implementFrom<&LocalType> for Box<LocalType>/Rc/Arc
which a new stdlibimpl<T: ?Sized + CloneToUninit> From<&T> for Box<T>
would conflict with whenLocalType: Clone
. Also, it would conflict with the existingimpl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a>
, whereE = &(dyn Error + 'a)
(sincealloc
cannot know thatcore
won't add animpl CloneToUninit for dyn Error + '_
).Links and related work
CloneToUninit
trait (tracking issue)Rc/Arc::make_mut
useCloneToUninit
to clone an existingT
already inside anRc/Arc
into a new, unique, heap allocation.impl<T: Clone> Clone for Box<T>
to be generalized toT: ?Sized + CloneToUninit
.What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
Second, if there's a concrete solution:
The text was updated successfully, but these errors were encountered: