-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking Issue for core::clone::CloneToUninit
trait
#126799
Comments
I thought about what a safer primitive could be that still enables what we need in impl<T, A> Rc<T, A>
where
T: ?Sized,
A: Allocator,
Box<T, RcAllocator<A>>: Clone,
{
pub fn make_mut(this: &mut Self) -> &mut T {...}
} where Lines 286 to 291 in fcae626
Then Instead of implementing an unsafe trait rust/library/alloc/src/boxed.rs Lines 2218 to 2222 in fcae626
What I don't know is whether |
One thing that this doesn't help with, that the current |
Tangentially, a generic way to build a container type and then clone or write into its uninitialized payload slot would fit nicely into a solution for rust-lang/wg-allocators#90 |
https://doc.rust-lang.org/nightly/std/clone/trait.CloneToUninit.html#implementors I think we should consider adding |
The std-dev-guide says we should use private specialization traits, which we do in most places. The implementation PR promoted a private trait to a public one, so it should have changed the specialization to a subtrait. |
I have implemented this suggestion in #126877 (scope creep, yay). Also, this has an additional benefit of no longer needing any
|
…olnay CloneToUninit impls As per rust-lang#126799. Also implements it for `Wtf8` and both versions of `os_str::Slice`. Maybe it is worth to slap `#[inline]` on some of those impls. r? `@dtolnay`
CloneToUninit impls As per rust-lang#126799. Also implements it for `Wtf8` and both versions of `os_str::Slice`. Maybe it is worth to slap `#[inline]` on some of those impls. r? `@dtolnay`
CloneToUninit impls As per rust-lang#126799. Also implements it for `Wtf8` and both versions of `os_str::Slice`. Maybe it is worth to slap `#[inline]` on some of those impls. r? `@dtolnay`
why does this take |
|
One of the implementation steps listed in this issue is “Convert To solve this problem, I tried writing a specialization trait which used error: cannot specialize on trait `Clone`
--> library/alloc/src/boxed.rs:1825:25
|
1825 | impl<T: CloneToUninit + Clone> SpecCloneBoxFrom for T {
| ^^^^^ which I read is a restriction to prevent lifetime specialization unsoundness, so this seems like an unsolvable problem, but I’m not particularly familiar with tricks for stdlib specialization. I’m posting this comment in the hopes that someone else can come up with a way that does work without regressing |
One thing I tried was making Then, we can have a single master...zachs18:rust:clone_unsized (ignore the last "stash" commit, that was something additional I was trying) This seems to work well, but does complicate the API somewhat. |
…mulacrum Expand `CloneToUninit` documentation. * Clarify relationship to `dyn` after rust-lang#133003. * Add an example of using it with `dyn` as rust-lang#133003 enabled. * Replace parameter name `dst` with `dest` to avoid confusion between abbreviations for “DeSTination” and “Dynamically-Sized Type”. * Add an example of implementing it. * Add links to Rust Reference for the mentioned concepts. * Mention that its method should rarely be called. * Various small corrections. Please review the `unsafe` code closely, as I am not an expert in the best possible ways to express these operations. (It might also be better to omit the implementation example entirely.) cc `@zachs18` rust-lang#126799
Rollup merge of rust-lang#133055 - kpreid:clone-uninit-doc, r=Mark-Simulacrum Expand `CloneToUninit` documentation. * Clarify relationship to `dyn` after rust-lang#133003. * Add an example of using it with `dyn` as rust-lang#133003 enabled. * Replace parameter name `dst` with `dest` to avoid confusion between abbreviations for “DeSTination” and “Dynamically-Sized Type”. * Add an example of implementing it. * Add links to Rust Reference for the mentioned concepts. * Mention that its method should rarely be called. * Various small corrections. Please review the `unsafe` code closely, as I am not an expert in the best possible ways to express these operations. (It might also be better to omit the implementation example entirely.) cc `@zachs18` rust-lang#126799
I copied the impl<T: ?Sized + CloneToUninit> Box<T> {
/// Clone an unsized value into a new [`Box`].
fn clone_unsized_from(value: &T) -> Self {
// Allocate the space for the value
let layout = Layout::for_value(value);
let ptr: *mut u8 = unsafe { core::alloc::alloc(layout) };
// Clone into the allocated space
let ptr: *mut T = todo!(); // How to do this in stable code??
unsafe { value.clone_to_uninit(ptr) };
// Even if .clone_to_uninit() took '*mut ()', this call would still need '*mut T'.
unsafe { Self::from_raw(ptr) }
}
} If I do have a workaround, but it is not dyn-compatible. I added a new method, unsafe impl<T: Clone> CloneToUninit for [T] {
unsafe fn clone_to_uninit(...) { ... }
fn ptr_with_address(&self, addr: *mut ()) -> *mut Self {
// The metadata is the slice length: add it manually.
core::ptr::slice_from_raw_parts_mut(addr.cast(), self.len())
}
}
unsafe impl CloneToUninit for i32 {
unsafe fn clone_to_uninit(...) { ... }
fn ptr_with_address(&self, addr: *mut ()) -> *mut Self {
// Since 'Self' is sized, this is a trivial cast.
addr as *mut Self
}
}
struct Foo(i32, [u8]);
unsafe impl CloneToUninit for Foo {
unsafe fn clone_to_uninit(...) { ... }
fn ptr_with_address(&self, addr: *mut ()) -> *mut Self {
// In this method, the compiler knows that `Self` and `[u8]` have
// the same metadata, so it allows casting pointers between them.
self.1.ptr_with_address(addr) as *mut Self
}
} Now Is the plan to stabilize |
…mulacrum Expand `CloneToUninit` documentation. * Clarify relationship to `dyn` after rust-lang#133003. * Add an example of using it with `dyn` as rust-lang#133003 enabled. * Replace parameter name `dst` with `dest` to avoid confusion between abbreviations for “DeSTination” and “Dynamically-Sized Type”. * Add an example of implementing it. * Add links to Rust Reference for the mentioned concepts. * Mention that its method should rarely be called. * Various small corrections. Please review the `unsafe` code closely, as I am not an expert in the best possible ways to express these operations. (It might also be better to omit the implementation example entirely.) cc `@zachs18` rust-lang#126799
Feature gate:
#![feature(clone_to_uninit)]
This is a tracking issue for
CloneToUninit
and its impls. This trait backs the behavior ofRc::make_mut
andArc::make_mut
, and likely in the future alsoBox::clone
.Public API
Steps / History
{Rc,Arc}::make_mut()
to unsized types. #116113Box::clone
to be based onCloneToUninit
Unresolved Questions
*mut ()
in the signature instead of*mut Self
. This makes CloneToUninit dyn-safe. Generalize{Rc,Arc}::make_mut()
to unsized types. #116113 (comment)Footnotes
https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html ↩
The text was updated successfully, but these errors were encountered: