@@ -232,20 +232,20 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
232232pub unsafe trait CloneToUninit {
233233 /// Performs copy-assignment from `self` to `dst`.
234234 ///
235- /// This is analogous to `std::ptr::write(dst, self.clone())`,
235+ /// This is analogous to `std::ptr::write(dst.cast() , self.clone())`,
236236 /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)).
237237 ///
238238 /// Before this function is called, `dst` may point to uninitialized memory.
239239 /// After this function is called, `dst` will point to initialized memory; it will be
240- /// sound to create a `&Self` reference from the pointer.
240+ /// sound to create a `&Self` reference from the pointer with the [pointer metadata]
241+ /// from `self`.
241242 ///
242243 /// # Safety
243244 ///
244245 /// Behavior is undefined if any of the following conditions are violated:
245246 ///
246- /// * `dst` must be [valid] for writes.
247- /// * `dst` must be properly aligned.
248- /// * `dst` must have the same [pointer metadata] (slice length or `dyn` vtable) as `self`.
247+ /// * `dst` must be [valid] for writes for `std::mem::size_of_val(self)` bytes.
248+ /// * `dst` must be properly aligned to `std::mem::align_of_val(self)`.
249249 ///
250250 /// [valid]: crate::ptr#safety
251251 /// [pointer metadata]: crate::ptr::metadata()
@@ -266,23 +266,24 @@ pub unsafe trait CloneToUninit {
266266 /// that might have already been created. (For example, if a `[Foo]` of length 3 is being
267267 /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
268268 /// cloned should be dropped.)
269- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) ;
269+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) ;
270270}
271271
272272#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
273273unsafe impl < T : Clone > CloneToUninit for T {
274274 #[ inline]
275- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
275+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
276276 // SAFETY: we're calling a specialization with the same contract
277- unsafe { <T as self :: uninit:: CopySpec >:: clone_one ( self , dst) }
277+ unsafe { <T as self :: uninit:: CopySpec >:: clone_one ( self , dst. cast :: < T > ( ) ) }
278278 }
279279}
280280
281281#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
282282unsafe impl < T : Clone > CloneToUninit for [ T ] {
283283 #[ inline]
284284 #[ cfg_attr( debug_assertions, track_caller) ]
285- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
285+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
286+ let dst: * mut [ T ] = dst. with_metadata_of ( self ) ;
286287 // SAFETY: we're calling a specialization with the same contract
287288 unsafe { <T as self :: uninit:: CopySpec >:: clone_slice ( self , dst) }
288289 }
@@ -292,21 +293,21 @@ unsafe impl<T: Clone> CloneToUninit for [T] {
292293unsafe impl CloneToUninit for str {
293294 #[ inline]
294295 #[ cfg_attr( debug_assertions, track_caller) ]
295- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
296+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
296297 // SAFETY: str is just a [u8] with UTF-8 invariant
297- unsafe { self . as_bytes ( ) . clone_to_uninit ( dst as * mut [ u8 ] ) }
298+ unsafe { self . as_bytes ( ) . clone_to_uninit ( dst) }
298299 }
299300}
300301
301302#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
302303unsafe impl CloneToUninit for crate :: ffi:: CStr {
303304 #[ cfg_attr( debug_assertions, track_caller) ]
304- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
305+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
305306 // SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants.
306307 // And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul).
307- // The pointer metadata properly preserves the length (NUL included ).
308+ // The pointer metadata properly preserves the length (so NUL is also copied ).
308309 // See: `cstr_metadata_is_length_with_nul` in tests.
309- unsafe { self . to_bytes_with_nul ( ) . clone_to_uninit ( dst as * mut [ u8 ] ) }
310+ unsafe { self . to_bytes_with_nul ( ) . clone_to_uninit ( dst) }
310311 }
311312}
312313
0 commit comments