@@ -262,43 +262,159 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
262262 _field : crate :: marker:: PhantomData < T > ,
263263}
264264
265- /// A generalization of [`Clone`] to dynamically-sized types stored in arbitrary containers.
265+ /// A generalization of [`Clone`] to [ dynamically-sized types][DST] stored in arbitrary containers.
266266///
267- /// This trait is implemented for all types implementing [`Clone`], and also [slices](slice) of all
268- /// such types. You may also implement this trait to enable cloning trait objects and custom DSTs
269- /// (structures containing dynamically-sized fields).
267+ /// This trait is implemented for all types implementing [`Clone`], [slices](slice) of all
268+ /// such types, and other dynamically-sized types in the standard library.
269+ /// You may also implement this trait to enable cloning custom DSTs
270+ /// (structures containing dynamically-sized fields), or use it as a supertrait to enable
271+ /// cloning a [trait object].
272+ ///
273+ /// This trait is normally used via operations on container types which support DSTs,
274+ /// so you should not typically need to call `.clone_to_uninit()` explicitly except when
275+ /// implementing such a container or otherwise performing explicit management of an allocation,
276+ /// or when implementing `CloneToUninit` itself.
270277///
271278/// # Safety
272279///
273- /// Implementations must ensure that when `.clone_to_uninit(dst)` returns normally rather than
274- /// panicking, it always leaves `*dst` initialized as a valid value of type `Self`.
280+ /// Implementations must ensure that when `.clone_to_uninit(dest)` returns normally rather than
281+ /// panicking, it always leaves `*dest` initialized as a valid value of type `Self`.
282+ ///
283+ /// # Examples
284+ ///
285+ // FIXME(#126799): when `Box::clone` allows use of `CloneToUninit`, rewrite these examples with it
286+ // since `Rc` is a distraction.
287+ ///
288+ /// If you are defining a trait, you can add `CloneToUninit` as a supertrait to enable cloning of
289+ /// `dyn` values of your trait:
290+ ///
291+ /// ```
292+ /// #![feature(clone_to_uninit)]
293+ /// use std::rc::Rc;
294+ ///
295+ /// trait Foo: std::fmt::Debug + std::clone::CloneToUninit {
296+ /// fn modify(&mut self);
297+ /// fn value(&self) -> i32;
298+ /// }
299+ ///
300+ /// impl Foo for i32 {
301+ /// fn modify(&mut self) {
302+ /// *self *= 10;
303+ /// }
304+ /// fn value(&self) -> i32 {
305+ /// *self
306+ /// }
307+ /// }
308+ ///
309+ /// let first: Rc<dyn Foo> = Rc::new(1234);
310+ ///
311+ /// let mut second = first.clone();
312+ /// Rc::make_mut(&mut second).modify(); // make_mut() will call clone_to_uninit()
313+ ///
314+ /// assert_eq!(first.value(), 1234);
315+ /// assert_eq!(second.value(), 12340);
316+ /// ```
317+ ///
318+ /// The following is an example of implementing `CloneToUninit` for a custom DST.
319+ /// (It is essentially a limited form of what `derive(CloneToUninit)` would do,
320+ /// if such a derive macro existed.)
275321///
276- /// # See also
322+ /// ```
323+ /// #![feature(clone_to_uninit)]
324+ /// use std::clone::CloneToUninit;
325+ /// use std::mem::offset_of;
326+ /// use std::rc::Rc;
327+ ///
328+ /// #[derive(PartialEq)]
329+ /// struct MyDst<T: ?Sized> {
330+ /// label: String,
331+ /// contents: T,
332+ /// }
277333///
278- /// * [`Clone::clone_from`] is a safe function which may be used instead when `Self` is a [`Sized`]
334+ /// unsafe impl<T: ?Sized + CloneToUninit> CloneToUninit for MyDst<T> {
335+ /// unsafe fn clone_to_uninit(&self, dest: *mut u8) {
336+ /// // The offset of `self.contents` is dynamic because it depends on the alignment of T
337+ /// // which can be dynamic (if `T = dyn SomeTrait`). Therefore, we have to obtain it
338+ /// // dynamically by examining `self`, rather than using `offset_of!`.
339+ /// //
340+ /// // SAFETY: `self` by definition points somewhere before `&self.contents` in the same
341+ /// // allocation.
342+ /// let offset_of_contents = unsafe {
343+ /// (&raw const self.contents).byte_offset_from_unsigned(self)
344+ /// };
345+ ///
346+ /// // Clone the *sized* fields of `self` (just one, in this example).
347+ /// // (By cloning this first and storing it temporarily in a local variable, we avoid
348+ /// // leaking it in case of any panic, using the ordinary automatic cleanup of local
349+ /// // variables. Such a leak would be sound, but undesirable.)
350+ /// let label = self.label.clone();
351+ ///
352+ /// // SAFETY: The caller must provide a `dest` such that these field offsets are valid
353+ /// // to write to.
354+ /// unsafe {
355+ /// // Clone the unsized field directly from `self` to `dest`.
356+ /// self.contents.clone_to_uninit(dest.add(offset_of_contents));
357+ ///
358+ /// // Now write all the sized fields.
359+ /// //
360+ /// // Note that we only do this once all of the clone() and clone_to_uninit() calls
361+ /// // have completed, and therefore we know that there are no more possible panics;
362+ /// // this ensures no memory leaks in case of panic.
363+ /// dest.add(offset_of!(Self, label)).cast::<String>().write(label);
364+ /// }
365+ /// // All fields of the struct have been initialized; therefore, the struct is initialized,
366+ /// // and we have satisfied our `unsafe impl CloneToUninit` obligations.
367+ /// }
368+ /// }
369+ ///
370+ /// fn main() {
371+ /// // Construct MyDst<[u8; 4]>, then coerce to MyDst<[u8]>.
372+ /// let first: Rc<MyDst<[u8]>> = Rc::new(MyDst {
373+ /// label: String::from("hello"),
374+ /// contents: [1, 2, 3, 4],
375+ /// });
376+ ///
377+ /// let mut second = first.clone();
378+ /// // make_mut() will call clone_to_uninit().
379+ /// for elem in Rc::make_mut(&mut second).contents.iter_mut() {
380+ /// *elem *= 10;
381+ /// }
382+ ///
383+ /// assert_eq!(first.contents, [1, 2, 3, 4]);
384+ /// assert_eq!(second.contents, [10, 20, 30, 40]);
385+ /// assert_eq!(second.label, "hello");
386+ /// }
387+ /// ```
388+ ///
389+ /// # See Also
390+ ///
391+ /// * [`Clone::clone_from`] is a safe function which may be used instead when [`Self: Sized`](Sized)
279392/// and the destination is already initialized; it may be able to reuse allocations owned by
280- /// the destination.
393+ /// the destination, whereas `clone_to_uninit` cannot, since its destination is assumed to be
394+ /// uninitialized.
281395/// * [`ToOwned`], which allocates a new destination container.
282396///
283397/// [`ToOwned`]: ../../std/borrow/trait.ToOwned.html
398+ /// [DST]: https://doc.rust-lang.org/reference/dynamically-sized-types.html
399+ /// [trait object]: https://doc.rust-lang.org/reference/types/trait-object.html
284400#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
285401pub unsafe trait CloneToUninit {
286- /// Performs copy-assignment from `self` to `dst `.
402+ /// Performs copy-assignment from `self` to `dest `.
287403 ///
288- /// This is analogous to `std::ptr::write(dst .cast(), self.clone())`,
289- /// except that `self ` may be a dynamically-sized type ([`!Sized`](Sized)).
404+ /// This is analogous to `std::ptr::write(dest .cast(), self.clone())`,
405+ /// except that `Self ` may be a dynamically-sized type ([`!Sized`](Sized)).
290406 ///
291- /// Before this function is called, `dst ` may point to uninitialized memory.
292- /// After this function is called, `dst ` will point to initialized memory; it will be
407+ /// Before this function is called, `dest ` may point to uninitialized memory.
408+ /// After this function is called, `dest ` will point to initialized memory; it will be
293409 /// sound to create a `&Self` reference from the pointer with the [pointer metadata]
294410 /// from `self`.
295411 ///
296412 /// # Safety
297413 ///
298414 /// Behavior is undefined if any of the following conditions are violated:
299415 ///
300- /// * `dst ` must be [valid] for writes for `size_of_val(self)` bytes.
301- /// * `dst ` must be properly aligned to `align_of_val(self)`.
416+ /// * `dest ` must be [valid] for writes for `size_of_val(self)` bytes.
417+ /// * `dest ` must be properly aligned to `align_of_val(self)`.
302418 ///
303419 /// [valid]: crate::ptr#safety
304420 /// [pointer metadata]: crate::ptr::metadata()
@@ -307,60 +423,59 @@ pub unsafe trait CloneToUninit {
307423 ///
308424 /// This function may panic. (For example, it might panic if memory allocation for a clone
309425 /// of a value owned by `self` fails.)
310- /// If the call panics, then `*dst ` should be treated as uninitialized memory; it must not be
426+ /// If the call panics, then `*dest ` should be treated as uninitialized memory; it must not be
311427 /// read or dropped, because even if it was previously valid, it may have been partially
312428 /// overwritten.
313429 ///
314- /// The caller may also need to take care to deallocate the allocation pointed to by `dst`,
315- /// if applicable, to avoid a memory leak, and may need to take other precautions to ensure
316- /// soundness in the presence of unwinding.
430+ /// The caller may wish to to take care to deallocate the allocation pointed to by `dest`,
431+ /// if applicable, to avoid a memory leak (but this is not a requirement).
317432 ///
318433 /// Implementors should avoid leaking values by, upon unwinding, dropping all component values
319434 /// that might have already been created. (For example, if a `[Foo]` of length 3 is being
320435 /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
321436 /// cloned should be dropped.)
322- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) ;
437+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) ;
323438}
324439
325440#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
326441unsafe impl < T : Clone > CloneToUninit for T {
327442 #[ inline]
328- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
443+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) {
329444 // SAFETY: we're calling a specialization with the same contract
330- unsafe { <T as self :: uninit:: CopySpec >:: clone_one ( self , dst . cast :: < T > ( ) ) }
445+ unsafe { <T as self :: uninit:: CopySpec >:: clone_one ( self , dest . cast :: < T > ( ) ) }
331446 }
332447}
333448
334449#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
335450unsafe impl < T : Clone > CloneToUninit for [ T ] {
336451 #[ inline]
337452 #[ cfg_attr( debug_assertions, track_caller) ]
338- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
339- let dst : * mut [ T ] = dst . with_metadata_of ( self ) ;
453+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) {
454+ let dest : * mut [ T ] = dest . with_metadata_of ( self ) ;
340455 // SAFETY: we're calling a specialization with the same contract
341- unsafe { <T as self :: uninit:: CopySpec >:: clone_slice ( self , dst ) }
456+ unsafe { <T as self :: uninit:: CopySpec >:: clone_slice ( self , dest ) }
342457 }
343458}
344459
345460#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
346461unsafe impl CloneToUninit for str {
347462 #[ inline]
348463 #[ cfg_attr( debug_assertions, track_caller) ]
349- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
464+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) {
350465 // SAFETY: str is just a [u8] with UTF-8 invariant
351- unsafe { self . as_bytes ( ) . clone_to_uninit ( dst ) }
466+ unsafe { self . as_bytes ( ) . clone_to_uninit ( dest ) }
352467 }
353468}
354469
355470#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
356471unsafe impl CloneToUninit for crate :: ffi:: CStr {
357472 #[ cfg_attr( debug_assertions, track_caller) ]
358- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
473+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) {
359474 // SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants.
360475 // And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul).
361476 // The pointer metadata properly preserves the length (so NUL is also copied).
362477 // See: `cstr_metadata_is_length_with_nul` in tests.
363- unsafe { self . to_bytes_with_nul ( ) . clone_to_uninit ( dst ) }
478+ unsafe { self . to_bytes_with_nul ( ) . clone_to_uninit ( dest ) }
364479 }
365480}
366481
0 commit comments