@@ -262,43 +262,159 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
262
262
_field : crate :: marker:: PhantomData < T > ,
263
263
}
264
264
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.
266
266
///
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.
270
277
///
271
278
/// # Safety
272
279
///
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.)
275
321
///
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
+ /// }
277
333
///
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)
279
392
/// 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.
281
395
/// * [`ToOwned`], which allocates a new destination container.
282
396
///
283
397
/// [`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
284
400
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
285
401
pub unsafe trait CloneToUninit {
286
- /// Performs copy-assignment from `self` to `dst `.
402
+ /// Performs copy-assignment from `self` to `dest `.
287
403
///
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)).
290
406
///
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
293
409
/// sound to create a `&Self` reference from the pointer with the [pointer metadata]
294
410
/// from `self`.
295
411
///
296
412
/// # Safety
297
413
///
298
414
/// Behavior is undefined if any of the following conditions are violated:
299
415
///
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)`.
302
418
///
303
419
/// [valid]: crate::ptr#safety
304
420
/// [pointer metadata]: crate::ptr::metadata()
@@ -307,60 +423,59 @@ pub unsafe trait CloneToUninit {
307
423
///
308
424
/// This function may panic. (For example, it might panic if memory allocation for a clone
309
425
/// 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
311
427
/// read or dropped, because even if it was previously valid, it may have been partially
312
428
/// overwritten.
313
429
///
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).
317
432
///
318
433
/// Implementors should avoid leaking values by, upon unwinding, dropping all component values
319
434
/// that might have already been created. (For example, if a `[Foo]` of length 3 is being
320
435
/// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
321
436
/// cloned should be dropped.)
322
- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) ;
437
+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) ;
323
438
}
324
439
325
440
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
326
441
unsafe impl < T : Clone > CloneToUninit for T {
327
442
#[ inline]
328
- unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
443
+ unsafe fn clone_to_uninit ( & self , dest : * mut u8 ) {
329
444
// 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 > ( ) ) }
331
446
}
332
447
}
333
448
334
449
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
335
450
unsafe impl < T : Clone > CloneToUninit for [ T ] {
336
451
#[ inline]
337
452
#[ 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 ) ;
340
455
// 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 ) }
342
457
}
343
458
}
344
459
345
460
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
346
461
unsafe impl CloneToUninit for str {
347
462
#[ inline]
348
463
#[ 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 ) {
350
465
// 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 ) }
352
467
}
353
468
}
354
469
355
470
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
356
471
unsafe impl CloneToUninit for crate :: ffi:: CStr {
357
472
#[ 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 ) {
359
474
// SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants.
360
475
// And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul).
361
476
// The pointer metadata properly preserves the length (so NUL is also copied).
362
477
// 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 ) }
364
479
}
365
480
}
366
481
0 commit comments