|  | 
| 36 | 36 | 
 | 
| 37 | 37 | #![stable(feature = "rust1", since = "1.0.0")] | 
| 38 | 38 | 
 | 
|  | 39 | +use crate::mem::{self, MaybeUninit}; | 
|  | 40 | +use crate::ptr; | 
|  | 41 | + | 
| 39 | 42 | /// A common trait for the ability to explicitly duplicate an object. | 
| 40 | 43 | /// | 
| 41 | 44 | /// 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> { | 
| 204 | 207 |     _field: crate::marker::PhantomData<T>, | 
| 205 | 208 | } | 
| 206 | 209 | 
 | 
|  | 210 | +/// 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 | + | 
| 207 | 393 | /// Implementations of `Clone` for primitive types. | 
| 208 | 394 | /// | 
| 209 | 395 | /// Implementations that cannot be described in Rust | 
|  | 
0 commit comments