@@ -1409,6 +1409,208 @@ impl<T> MaybeUninit<T> {
14091409 unsafe { slice:: from_raw_parts_mut ( this. as_mut_ptr ( ) as * mut MaybeUninit < u8 > , bytes) }
14101410 }
14111411}
1412+ impl < T > [ MaybeUninit < T > ] {
1413+ /// Copies the elements from `src` to `self`,
1414+ /// returning a mutable reference to the now initialized contents of `self`.
1415+ ///
1416+ /// If `T` does not implement `Copy`, use [`write_clone_of_slice`] instead.
1417+ ///
1418+ /// This is similar to [`slice::copy_from_slice`].
1419+ ///
1420+ /// # Panics
1421+ ///
1422+ /// This function will panic if the two slices have different lengths.
1423+ ///
1424+ /// # Examples
1425+ ///
1426+ /// ```
1427+ /// #![feature(maybe_uninit_write_slice)]
1428+ /// use std::mem::MaybeUninit;
1429+ ///
1430+ /// let mut dst = [MaybeUninit::uninit(); 32];
1431+ /// let src = [0; 32];
1432+ ///
1433+ /// let init = dst.write_copy_of_slice(&src);
1434+ ///
1435+ /// assert_eq!(init, src);
1436+ /// ```
1437+ ///
1438+ /// ```
1439+ /// #![feature(maybe_uninit_write_slice)]
1440+ ///
1441+ /// let mut vec = Vec::with_capacity(32);
1442+ /// let src = [0; 16];
1443+ ///
1444+ /// vec.spare_capacity_mut()[..src.len()].write_copy_of_slice(&src);
1445+ ///
1446+ /// // SAFETY: we have just copied all the elements of len into the spare capacity
1447+ /// // the first src.len() elements of the vec are valid now.
1448+ /// unsafe {
1449+ /// vec.set_len(src.len());
1450+ /// }
1451+ ///
1452+ /// assert_eq!(vec, src);
1453+ /// ```
1454+ ///
1455+ /// [`write_clone_of_slice`]: MaybeUninit::write_clone_of_slice
1456+ #[ unstable( feature = "maybe_uninit_write_slice" , issue = "79995" ) ]
1457+ pub fn write_copy_of_slice ( & mut self , src : & [ T ] ) -> & mut [ T ]
1458+ where
1459+ T : Copy ,
1460+ {
1461+ // SAFETY: &[T] and &[MaybeUninit<T>] have the same layout
1462+ let uninit_src: & [ MaybeUninit < T > ] = unsafe { super :: transmute ( src) } ;
1463+
1464+ self . copy_from_slice ( uninit_src) ;
1465+
1466+ // SAFETY: Valid elements have just been copied into `self` so it is initialized
1467+ unsafe { self . assume_init_mut ( ) }
1468+ }
1469+
1470+ /// Clones the elements from `src` to `self`,
1471+ /// returning a mutable reference to the now initialized contents of `self`.
1472+ /// Any already initialized elements will not be dropped.
1473+ ///
1474+ /// If `T` implements `Copy`, use [`write_copy_of_slice`] instead.
1475+ ///
1476+ /// This is similar to [`slice::clone_from_slice`] but does not drop existing elements.
1477+ ///
1478+ /// # Panics
1479+ ///
1480+ /// This function will panic if the two slices have different lengths, or if the implementation of `Clone` panics.
1481+ ///
1482+ /// If there is a panic, the already cloned elements will be dropped.
1483+ ///
1484+ /// # Examples
1485+ ///
1486+ /// ```
1487+ /// #![feature(maybe_uninit_write_slice)]
1488+ /// use std::mem::MaybeUninit;
1489+ ///
1490+ /// let mut dst = [const { MaybeUninit::uninit() }; 5];
1491+ /// let src = ["wibbly", "wobbly", "timey", "wimey", "stuff"].map(|s| s.to_string());
1492+ ///
1493+ /// let init = dst.write_clone_of_slice(&src);
1494+ ///
1495+ /// assert_eq!(init, src);
1496+ ///
1497+ /// # // Prevent leaks for Miri
1498+ /// # unsafe { std::ptr::drop_in_place(init); }
1499+ /// ```
1500+ ///
1501+ /// ```
1502+ /// #![feature(maybe_uninit_write_slice)]
1503+ ///
1504+ /// let mut vec = Vec::with_capacity(32);
1505+ /// let src = ["rust", "is", "a", "pretty", "cool", "language"].map(|s| s.to_string());
1506+ ///
1507+ /// vec.spare_capacity_mut()[..src.len()].write_clone_of_slice(&src);
1508+ ///
1509+ /// // SAFETY: we have just cloned all the elements of len into the spare capacity
1510+ /// // the first src.len() elements of the vec are valid now.
1511+ /// unsafe {
1512+ /// vec.set_len(src.len());
1513+ /// }
1514+ ///
1515+ /// assert_eq!(vec, src);
1516+ /// ```
1517+ ///
1518+ /// [`write_copy_of_slice`]: MaybeUninit::write_copy_of_slice
1519+ #[ unstable( feature = "maybe_uninit_write_slice" , issue = "79995" ) ]
1520+ pub fn write_clone_of_slice ( & mut self , src : & [ T ] ) -> & mut [ T ]
1521+ where
1522+ T : Clone ,
1523+ {
1524+ // unlike copy_from_slice this does not call clone_from_slice on the slice
1525+ // this is because `MaybeUninit<T: Clone>` does not implement Clone.
1526+
1527+ assert_eq ! ( self . len( ) , src. len( ) , "destination and source slices have different lengths" ) ;
1528+
1529+ // NOTE: We need to explicitly slice them to the same length
1530+ // for bounds checking to be elided, and the optimizer will
1531+ // generate memcpy for simple cases (for example T = u8).
1532+ let len = self . len ( ) ;
1533+ let src = & src[ ..len] ;
1534+
1535+ // guard is needed b/c panic might happen during a clone
1536+ let mut guard = Guard { slice : self , initialized : 0 } ;
1537+
1538+ for i in 0 ..len {
1539+ guard. slice [ i] . write ( src[ i] . clone ( ) ) ;
1540+ guard. initialized += 1 ;
1541+ }
1542+
1543+ super :: forget ( guard) ;
1544+
1545+ // SAFETY: Valid elements have just been written into `self` so it is initialized
1546+ unsafe { self . assume_init_mut ( ) }
1547+ }
1548+
1549+ /// Drops the contained values in place.
1550+ ///
1551+ /// # Safety
1552+ ///
1553+ /// It is up to the caller to guarantee that every `MaybeUninit<T>` in the slice
1554+ /// really is in an initialized state. Calling this when the content is not yet
1555+ /// fully initialized causes undefined behavior.
1556+ ///
1557+ /// On top of that, all additional invariants of the type `T` must be
1558+ /// satisfied, as the `Drop` implementation of `T` (or its members) may
1559+ /// rely on this. For example, setting a [`Vec<T>`] to an invalid but
1560+ /// non-null address makes it initialized (under the current implementation;
1561+ /// this does not constitute a stable guarantee), because the only
1562+ /// requirement the compiler knows about it is that the data pointer must be
1563+ /// non-null. Dropping such a `Vec<T>` however will cause undefined
1564+ /// behaviour.
1565+ ///
1566+ /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
1567+ #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1568+ pub unsafe fn assume_init_drop ( & mut self ) {
1569+ // SAFETY: the caller must guarantee that every element of `self`
1570+ // is initialized and satisfies all invariants of `T`.
1571+ // Dropping the value in place is safe if that is the case.
1572+ unsafe { ptr:: drop_in_place ( self as * mut [ MaybeUninit < T > ] as * mut [ T ] ) }
1573+ }
1574+
1575+ /// Gets a shared reference to the contained value.
1576+ ///
1577+ /// # Safety
1578+ ///
1579+ /// Calling this when the content is not yet fully initialized causes undefined
1580+ /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in
1581+ /// the slice really is in an initialized state.
1582+ #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1583+ #[ rustc_const_unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1584+ #[ inline( always) ]
1585+ pub const unsafe fn assume_init_ref ( & self ) -> & [ T ] {
1586+ // SAFETY: the caller must guarantee that `self` is initialized.
1587+ // This also means that `self` must be a `value` variant.
1588+ unsafe {
1589+ intrinsics:: assert_inhabited :: < T > ( ) ;
1590+ slice:: from_raw_parts ( self . as_ptr ( ) . cast :: < T > ( ) , self . len ( ) )
1591+ }
1592+ }
1593+
1594+ /// Gets a mutable (unique) reference to the contained value.
1595+ ///
1596+ /// # Safety
1597+ ///
1598+ /// Calling this when the content is not yet fully initialized causes undefined
1599+ /// behavior: it is up to the caller to guarantee that every `MaybeUninit<T>` in the
1600+ /// slice really is in an initialized state. For instance, `.assume_init_mut()` cannot
1601+ /// be used to initialize a `MaybeUninit` slice.
1602+ #[ unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1603+ #[ rustc_const_unstable( feature = "maybe_uninit_slice" , issue = "63569" ) ]
1604+ #[ inline( always) ]
1605+ pub const unsafe fn assume_init_mut ( & mut self ) -> & mut [ T ] {
1606+ // SAFETY: the caller must guarantee that `self` is initialized.
1607+ // This also means that `self` must be a `value` variant.
1608+ unsafe {
1609+ intrinsics:: assert_inhabited :: < T > ( ) ;
1610+ slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) . cast :: < T > ( ) , self . len ( ) )
1611+ }
1612+ }
1613+ }
14121614
14131615impl < T , const N : usize > MaybeUninit < [ T ; N ] > {
14141616 /// Transposes a `MaybeUninit<[T; N]>` into a `[MaybeUninit<T>; N]`.
@@ -1459,7 +1661,7 @@ impl<'a, T> Drop for Guard<'a, T> {
14591661 let initialized_part = & mut self . slice [ ..self . initialized ] ;
14601662 // SAFETY: this raw sub-slice will contain only initialized objects.
14611663 unsafe {
1462- crate :: ptr :: drop_in_place ( MaybeUninit :: slice_assume_init_mut ( initialized_part) ) ;
1664+ initialized_part. assume_init_drop ( ) ;
14631665 }
14641666 }
14651667}
0 commit comments