@@ -232,20 +232,20 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> {
232
232
pub unsafe trait CloneToUninit {
233
233
/// Performs copy-assignment from `self` to `dst`.
234
234
///
235
- /// This is analogous to `std::ptr::write(dst, self.clone())`,
235
+ /// This is analogous to `std::ptr::write(dst.cast() , self.clone())`,
236
236
/// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)).
237
237
///
238
238
/// Before this function is called, `dst` may point to uninitialized memory.
239
239
/// 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`.
241
242
///
242
243
/// # Safety
243
244
///
244
245
/// Behavior is undefined if any of the following conditions are violated:
245
246
///
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)`.
249
249
///
250
250
/// [valid]: crate::ptr#safety
251
251
/// [pointer metadata]: crate::ptr::metadata()
@@ -266,23 +266,24 @@ pub unsafe trait CloneToUninit {
266
266
/// that might have already been created. (For example, if a `[Foo]` of length 3 is being
267
267
/// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo`
268
268
/// cloned should be dropped.)
269
- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) ;
269
+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) ;
270
270
}
271
271
272
272
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
273
273
unsafe impl < T : Clone > CloneToUninit for T {
274
274
#[ inline]
275
- unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
275
+ unsafe fn clone_to_uninit ( & self , dst : * mut u8 ) {
276
276
// 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 > ( ) ) }
278
278
}
279
279
}
280
280
281
281
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
282
282
unsafe impl < T : Clone > CloneToUninit for [ T ] {
283
283
#[ inline]
284
284
#[ 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 ) ;
286
287
// SAFETY: we're calling a specialization with the same contract
287
288
unsafe { <T as self :: uninit:: CopySpec >:: clone_slice ( self , dst) }
288
289
}
@@ -292,21 +293,21 @@ unsafe impl<T: Clone> CloneToUninit for [T] {
292
293
unsafe impl CloneToUninit for str {
293
294
#[ inline]
294
295
#[ 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 ) {
296
297
// 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) }
298
299
}
299
300
}
300
301
301
302
#[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
302
303
unsafe impl CloneToUninit for crate :: ffi:: CStr {
303
304
#[ 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 ) {
305
306
// SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants.
306
307
// 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 ).
308
309
// 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) }
310
311
}
311
312
}
312
313
0 commit comments