Add `core::clone::CloneToUninit`. · model-checking/verify-rust-std@a4ca461
@@ -36,6 +36,9 @@
36363737#![stable(feature = "rust1", since = "1.0.0")]
383839+use crate::mem::{self, MaybeUninit};
40+use crate::ptr;
41+3942/// A common trait for the ability to explicitly duplicate an object.
4043///
4144/// Differs from [`Copy`] in that [`Copy`] is implicit and an inexpensive bit-wise copy, while
@@ -204,6 +207,189 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
204207_field: crate::marker::PhantomData<T>,
205208}
206209210+/// A generalization of [`Clone`] to dynamically-sized types stored in arbitrary containers.
211+///
212+/// This trait is implemented for all types implementing [`Clone`], and also [slices](slice) of all
213+/// such types. You may also implement this trait to enable cloning trait objects and custom DSTs
214+/// (structures containing dynamically-sized fields).
215+///
216+/// # Safety
217+///
218+/// Implementations must ensure that when `.clone_to_uninit(dst)` returns normally rather than
219+/// panicking, it always leaves `*dst` initialized as a valid value of type `Self`.
220+///
221+/// # See also
222+///
223+/// * [`Clone::clone_from`] is a safe function which may be used instead when `Self` is a [`Sized`]
224+/// and the destination is already initialized; it may be able to reuse allocations owned by
225+/// the destination.
226+/// * [`ToOwned`], which allocates a new destination container.
227+///
228+/// [`ToOwned`]: ../../std/borrow/trait.ToOwned.html
229+#[unstable(feature = "clone_to_uninit", issue = "126799")]
230+pub unsafe trait CloneToUninit {
231+/// Performs copy-assignment from `self` to `dst`.
232+ ///
233+ /// This is analogous to to `std::ptr::write(dst, self.clone())`,
234+ /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)).
235+ ///
236+ /// Before this function is called, `dst` may point to uninitialized memory.
237+ /// After this function is called, `dst` will point to initialized memory; it will be
238+ /// sound to create a `&Self` reference from the pointer.
239+ ///
240+ /// # Safety
241+ ///
242+ /// Behavior is undefined if any of the following conditions are violated:
243+ ///
244+ /// * `dst` must be [valid] for writes.
245+ /// * `dst` must be properly aligned.
246+ /// * `dst` must have the same [pointer metadata] (slice length or `dyn` vtable) as `self`.
247+ ///
248+ /// [valid]: ptr#safety
249+ /// [pointer metadata]: crate::ptr::metadata()
250+ ///
251+ /// # Panics
252+ ///
253+ /// This function may panic. (For example, it might panic if memory allocation for a clone
254+ /// of a value owned by `self` fails.)
255+ /// If the call panics, then `*dst` should be treated as uninitialized memory; it must not be
256+ /// read or dropped, because even if it was previously valid, it may have been partially
257+ /// overwritten.
258+ ///
259+ /// The caller may also need to take care to deallocate the allocation pointed to by `dst`,
260+ /// if applicable, to avoid a memory leak, and may need to take other precautions to ensure
261+ /// soundness in the presence of unwinding.
262+ ///
263+ /// Implementors should avoid leaking values by, upon unwinding, dropping all component values
264+ /// that might have already been created. (For example, if a `[Foo]` of length 3 is being
265+ /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
266+ /// cloned should be dropped.)
267+ unsafe fn clone_to_uninit(&self, dst: *mut Self);
268+}
269+270+#[unstable(feature = "clone_to_uninit", issue = "126799")]
271+unsafe impl<T: Clone> CloneToUninit for T {
272+default unsafe fn clone_to_uninit(&self, dst: *mut Self) {
273+// SAFETY: The safety conditions of clone_to_uninit() are a superset of those of
274+// ptr::write().
275+unsafe {
276+// We hope the optimizer will figure out to create the cloned value in-place,
277+// skipping ever storing it on the stack and the copy to the destination.
278+ ptr::write(dst, self.clone());
279+}
280+}
281+}
282+283+// Specialized implementation for types that are [`Copy`], not just [`Clone`],
284+// and can therefore be copied bitwise.
285+#[unstable(feature = "clone_to_uninit", issue = "126799")]
286+unsafe impl<T: Copy> CloneToUninit for T {
287+unsafe fn clone_to_uninit(&self, dst: *mut Self) {
288+// SAFETY: The safety conditions of clone_to_uninit() are a superset of those of
289+// ptr::copy_nonoverlapping().
290+unsafe {
291+ ptr::copy_nonoverlapping(self, dst, 1);
292+}
293+}
294+}
295+296+#[unstable(feature = "clone_to_uninit", issue = "126799")]
297+unsafe impl<T: Clone> CloneToUninit for [T] {
298+#[cfg_attr(debug_assertions, track_caller)]
299+default unsafe fn clone_to_uninit(&self, dst: *mut Self) {
300+let len = self.len();
301+// This is the most likely mistake to make, so check it as a debug assertion.
302+debug_assert_eq!(
303+ len,
304+ dst.len(),
305+"clone_to_uninit() source and destination must have equal lengths",
306+);
307+308+// SAFETY: The produced `&mut` is valid because:
309+// * The caller is obligated to provide a pointer which is valid for writes.
310+// * All bytes pointed to are in MaybeUninit, so we don't care about the memory's
311+// initialization status.
312+let uninit_ref = unsafe { &mut *(dst as *mut [MaybeUninit<T>]) };
313+314+// Copy the elements
315+let mut initializing = InitializingSlice::from_fully_uninit(uninit_ref);
316+for element_ref in self.iter() {
317+// If the clone() panics, `initializing` will take care of the cleanup.
318+ initializing.push(element_ref.clone());
319+}
320+// If we reach here, then the entire slice is initialized, and we've satisfied our
321+// responsibilities to the caller. Disarm the cleanup guard by forgetting it.
322+ mem::forget(initializing);
323+}
324+}
325+326+#[unstable(feature = "clone_to_uninit", issue = "126799")]
327+unsafe impl<T: Copy> CloneToUninit for [T] {
328+#[cfg_attr(debug_assertions, track_caller)]
329+unsafe fn clone_to_uninit(&self, dst: *mut Self) {
330+let len = self.len();
331+// This is the most likely mistake to make, so check it as a debug assertion.
332+debug_assert_eq!(
333+ len,
334+ dst.len(),
335+"clone_to_uninit() source and destination must have equal lengths",
336+);
337+338+// SAFETY: The safety conditions of clone_to_uninit() are a superset of those of
339+// ptr::copy_nonoverlapping().
340+unsafe {
341+ ptr::copy_nonoverlapping(self.as_ptr(), dst.as_mut_ptr(), len);
342+}
343+}
344+}
345+346+/// Ownership of a collection of values stored in a non-owned `[MaybeUninit<T>]`, some of which
347+/// are not yet initialized. This is sort of like a `Vec` that doesn't own its allocation.
348+/// Its responsibility is to provide cleanup on unwind by dropping the values that *are*
349+/// initialized, unless disarmed by forgetting.
350+///
351+/// This is a helper for `impl<T: Clone> CloneToUninit for [T]`.
352+struct InitializingSlice<'a, T> {
353+data: &'a mut [MaybeUninit<T>],
354+/// Number of elements of `*self.data` that are initialized.
355+ initialized_len: usize,
356+}
357+358+impl<'a, T> InitializingSlice<'a, T> {
359+#[inline]
360+fn from_fully_uninit(data: &'a mut [MaybeUninit<T>]) -> Self {
361+Self { data, initialized_len: 0 }
362+}
363+364+/// Push a value onto the end of the initialized part of the slice.
365+ ///
366+ /// # Panics
367+ ///
368+ /// Panics if the slice is already fully initialized.
369+ #[inline]
370+fn push(&mut self, value: T) {
371+MaybeUninit::write(&mut self.data[self.initialized_len], value);
372+self.initialized_len += 1;
373+}
374+}
375+376+impl<'a, T> Drop for InitializingSlice<'a, T> {
377+#[cold] // will only be invoked on unwind
378+fn drop(&mut self) {
379+let initialized_slice = ptr::slice_from_raw_parts_mut(
380+MaybeUninit::slice_as_mut_ptr(self.data),
381+self.initialized_len,
382+);
383+// SAFETY:
384+// * the pointer is valid because it was made from a mutable reference
385+// * `initialized_len` counts the initialized elements as an invariant of this type,
386+// so each of the pointed-to elements is initialized and may be dropped.
387+unsafe {
388+ ptr::drop_in_place::<[T]>(initialized_slice);
389+}
390+}
391+}
392+207393/// Implementations of `Clone` for primitive types.
208394///
209395/// Implementations that cannot be described in Rust