@@ -205,8 +205,6 @@ use core::task::{Context, Poll};
205205use crate :: alloc:: handle_alloc_error;
206206use crate :: alloc:: { AllocError , Allocator , Global , Layout } ;
207207use crate :: raw_vec:: RawVec ;
208- #[ cfg( not( no_global_oom_handling) ) ]
209- use crate :: str:: from_boxed_utf8_unchecked;
210208
211209/// Conversion related impls for `Box<_>` (`From`, `downcast`, etc)
212210mod convert;
@@ -1733,7 +1731,7 @@ where
17331731
17341732#[ cfg( not( no_global_oom_handling) ) ]
17351733#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1736- impl < T : Clone , A : Allocator + Clone > Clone for Box < T , A > {
1734+ impl < T : CloneToUninit + ? Sized , A : Allocator + Clone > Clone for Box < T , A > {
17371735 /// Returns a new box with a `clone()` of this box's contents.
17381736 ///
17391737 /// # Examples
@@ -1751,14 +1749,21 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
17511749 #[ inline]
17521750 fn clone ( & self ) -> Self {
17531751 // Pre-allocate memory to allow writing the cloned value directly.
1754- let mut boxed = Self :: new_uninit_in ( self . 1 . clone ( ) ) ;
1752+ let mut boxed = unsafe {
1753+ uninit:: UninitBox :: < T , A > :: new_for_metadata_in (
1754+ ptr:: metadata ( Self :: as_ptr ( self ) ) ,
1755+ self . 1 . clone ( ) ,
1756+ )
1757+ } ;
1758+
17551759 unsafe {
17561760 ( * * self ) . clone_to_uninit ( boxed. as_mut_ptr ( ) . cast ( ) ) ;
17571761 boxed. assume_init ( )
17581762 }
17591763 }
17601764
1761- /// Copies `source`'s contents into `self` without creating a new allocation.
1765+ /// Copies `source`'s contents into `self` without creating a new allocation,
1766+ /// so long as the two have the same metadata.
17621767 ///
17631768 /// # Examples
17641769 ///
@@ -1777,55 +1782,16 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<T, A> {
17771782 /// ```
17781783 #[ inline]
17791784 fn clone_from ( & mut self , source : & Self ) {
1780- ( * * self ) . clone_from ( & ( * * source) ) ;
1781- }
1782- }
1783-
1784- #[ cfg( not( no_global_oom_handling) ) ]
1785- #[ stable( feature = "box_slice_clone" , since = "1.3.0" ) ]
1786- impl < T : Clone , A : Allocator + Clone > Clone for Box < [ T ] , A > {
1787- fn clone ( & self ) -> Self {
1788- let alloc = Box :: allocator ( self ) . clone ( ) ;
1789- self . to_vec_in ( alloc) . into_boxed_slice ( )
1790- }
1791-
1792- /// Copies `source`'s contents into `self` without creating a new allocation,
1793- /// so long as the two are of the same length.
1794- ///
1795- /// # Examples
1796- ///
1797- /// ```
1798- /// let x = Box::new([5, 6, 7]);
1799- /// let mut y = Box::new([8, 9, 10]);
1800- /// let yp: *const [i32] = &*y;
1801- ///
1802- /// y.clone_from(&x);
1803- ///
1804- /// // The value is the same
1805- /// assert_eq!(x, y);
1806- ///
1807- /// // And no allocation occurred
1808- /// assert_eq!(yp, &*y);
1809- /// ```
1810- fn clone_from ( & mut self , source : & Self ) {
1811- if self . len ( ) == source. len ( ) {
1812- self . clone_from_slice ( & source) ;
1785+ // The following comparison may fail for vtable pointers even if both
1786+ // types are the same, in which case we take the slow path.
1787+ if ptr:: metadata ( self ) == ptr:: metadata ( source) {
1788+ unsafe { ( * * source) . clone_to_init ( Box :: as_mut_ptr ( self ) . cast ( ) ) } ;
18131789 } else {
18141790 * self = source. clone ( ) ;
18151791 }
18161792 }
18171793}
18181794
1819- #[ cfg( not( no_global_oom_handling) ) ]
1820- #[ stable( feature = "box_slice_clone" , since = "1.3.0" ) ]
1821- impl Clone for Box < str > {
1822- fn clone ( & self ) -> Self {
1823- // this makes a copy of the data
1824- let buf: Box < [ u8 ] > = self . as_bytes ( ) . into ( ) ;
1825- unsafe { from_boxed_utf8_unchecked ( buf) }
1826- }
1827- }
1828-
18291795#[ stable( feature = "rust1" , since = "1.0.0" ) ]
18301796impl < T : ?Sized + PartialEq , A : Allocator > PartialEq for Box < T , A > {
18311797 #[ inline]
0 commit comments