File tree Expand file tree Collapse file tree 8 files changed +95
-0
lines changed Expand file tree Collapse file tree 8 files changed +95
-0
lines changed Original file line number Diff line number Diff line change 3
3
#[cfg(test)]
4
4
mod tests;
5
5
6
+ use core::clone::CloneToUninit;
7
+
6
8
use crate::borrow::{Borrow, Cow};
7
9
use crate::collections::TryReserveError;
8
10
use crate::hash::{Hash, Hasher};
9
11
use crate::ops::{self, Range};
12
+ use crate::ptr::addr_of_mut;
10
13
use crate::rc::Rc;
11
14
use crate::str::FromStr;
12
15
use crate::sync::Arc;
@@ -1261,6 +1264,15 @@ impl Clone for Box<OsStr> {
1261
1264
}
1262
1265
}
1263
1266
1267
+ #[unstable(feature = "clone_to_uninit", issue = "126799")]
1268
+ unsafe impl CloneToUninit for OsStr {
1269
+ #[cfg_attr(debug_assertions, track_caller)]
1270
+ unsafe fn clone_to_uninit(&self, dst: *mut Self) {
1271
+ // SAFETY: we're just a wrapper around a platform-specific Slice
1272
+ unsafe { self.inner.clone_to_uninit(addr_of_mut!((*dst).inner)) }
1273
+ }
1274
+ }
1275
+
1264
1276
#[stable(feature = "shared_from_slice2", since = "1.24.0")]
1265
1277
impl From<OsString> for Arc<OsStr> {
1266
1278
/// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> by moving the [`OsString`]
Original file line number Diff line number Diff line change 1
1
use super::*;
2
+ use crate::mem::MaybeUninit;
3
+ use crate::ptr;
2
4
3
5
#[test]
4
6
fn test_os_string_with_capacity() {
@@ -286,3 +288,18 @@ fn slice_surrogate_edge() {
286
288
assert_eq!(post_crab.slice_encoded_bytes(..4), "🦀");
287
289
assert_eq!(post_crab.slice_encoded_bytes(4..), surrogate);
288
290
}
291
+
292
+ #[test]
293
+ fn clone_to_uninit() {
294
+ let a = OsStr::new("hello.txt");
295
+
296
+ let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<OsStr>(a)];
297
+ unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut OsStr) };
298
+ assert_eq!(a.as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) });
299
+
300
+ let mut b: Box<OsStr> = OsStr::new("world.exe").into();
301
+ assert_eq!(size_of_val::<OsStr>(a), size_of_val::<OsStr>(&b));
302
+ assert_ne!(a, &*b);
303
+ unsafe { a.clone_to_uninit(ptr::from_mut::<OsStr>(&mut b)) };
304
+ assert_eq!(a, &*b);
305
+ }
Original file line number Diff line number Diff line change 323
323
// tidy-alphabetical-start
324
324
#![feature(c_str_module)]
325
325
#![feature(char_internals)]
326
+ #![feature(clone_to_uninit)]
326
327
#![feature(core_intrinsics)]
327
328
#![feature(core_io_borrowed_buf)]
328
329
#![feature(duration_constants)]
Original file line number Diff line number Diff line change 70
70
#[cfg(test)]
71
71
mod tests;
72
72
73
+ use core::clone::CloneToUninit;
74
+
73
75
use crate::borrow::{Borrow, Cow};
74
76
use crate::collections::TryReserveError;
75
77
use crate::error::Error;
@@ -3109,6 +3111,15 @@ impl Path {
3109
3111
}
3110
3112
}
3111
3113
3114
+ #[unstable(feature = "clone_to_uninit", issue = "126799")]
3115
+ unsafe impl CloneToUninit for Path {
3116
+ #[cfg_attr(debug_assertions, track_caller)]
3117
+ unsafe fn clone_to_uninit(&self, dst: *mut Self) {
3118
+ // SAFETY: Path is just a wrapper around OsStr
3119
+ unsafe { self.inner.clone_to_uninit(core::ptr::addr_of_mut!((*dst).inner)) }
3120
+ }
3121
+ }
3122
+
3112
3123
#[stable(feature = "rust1", since = "1.0.0")]
3113
3124
impl AsRef<OsStr> for Path {
3114
3125
#[inline]
Original file line number Diff line number Diff line change @@ -3,6 +3,8 @@ use core::hint::black_box;
3
3
use super::*;
4
4
use crate::collections::{BTreeSet, HashSet};
5
5
use crate::hash::DefaultHasher;
6
+ use crate::mem::MaybeUninit;
7
+ use crate::ptr;
6
8
7
9
#[allow(unknown_lints, unused_macro_rules)]
8
10
macro_rules! t (
@@ -2054,3 +2056,20 @@ fn bench_hash_path_long(b: &mut test::Bencher) {
2054
2056
2055
2057
black_box(hasher.finish());
2056
2058
}
2059
+
2060
+ #[test]
2061
+ fn clone_to_uninit() {
2062
+ let a = Path::new("hello.txt");
2063
+
2064
+ let mut storage = vec![MaybeUninit::<u8>::uninit(); size_of_val::<Path>(a)];
2065
+ unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut Path) };
2066
+ assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe {
2067
+ MaybeUninit::slice_assume_init_ref(&storage)
2068
+ });
2069
+
2070
+ let mut b: Box<Path> = Path::new("world.exe").into();
2071
+ assert_eq!(size_of_val::<Path>(a), size_of_val::<Path>(&b));
2072
+ assert_ne!(a, &*b);
2073
+ unsafe { a.clone_to_uninit(ptr::from_mut::<Path>(&mut b)) };
2074
+ assert_eq!(a, &*b);
2075
+ }
Original file line number Diff line number Diff line change 1
1
//! The underlying OsString/OsStr implementation on Unix and many other
2
2
//! systems: just a `Vec<u8>`/`[u8]`.
3
3
4
+ use core::clone::CloneToUninit;
5
+ use core::ptr::addr_of_mut;
6
+
4
7
use crate::borrow::Cow;
5
8
use crate::collections::TryReserveError;
6
9
use crate::fmt::Write;
@@ -345,3 +348,12 @@ impl Slice {
345
348
self.inner.eq_ignore_ascii_case(&other.inner)
346
349
}
347
350
}
351
+
352
+ #[unstable(feature = "clone_to_uninit", issue = "126799")]
353
+ unsafe impl CloneToUninit for Slice {
354
+ #[cfg_attr(debug_assertions, track_caller)]
355
+ unsafe fn clone_to_uninit(&self, dst: *mut Self) {
356
+ // SAFETY: we're just a wrapper around [u8]
357
+ unsafe { self.inner.clone_to_uninit(addr_of_mut!((*dst).inner)) }
358
+ }
359
+ }
Original file line number Diff line number Diff line change 1
1
//! The underlying OsString/OsStr implementation on Windows is a
2
2
//! wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
3
+ use core::clone::CloneToUninit;
4
+ use core::ptr::addr_of_mut;
5
+
3
6
use crate::borrow::Cow;
4
7
use crate::collections::TryReserveError;
5
8
use crate::rc::Rc;
@@ -268,3 +271,12 @@ impl Slice {
268
271
self.inner.eq_ignore_ascii_case(&other.inner)
269
272
}
270
273
}
274
+
275
+ #[unstable(feature = "clone_to_uninit", issue = "126799")]
276
+ unsafe impl CloneToUninit for Slice {
277
+ #[cfg_attr(debug_assertions, track_caller)]
278
+ unsafe fn clone_to_uninit(&self, dst: *mut Self) {
279
+ // SAFETY: we're just a wrapper around Wtf8
280
+ unsafe { self.inner.clone_to_uninit(addr_of_mut!((*dst).inner)) }
281
+ }
282
+ }
Original file line number Diff line number Diff line change 19
19
mod tests;
20
20
21
21
use core::char::{encode_utf16_raw, encode_utf8_raw};
22
+ use core::clone::CloneToUninit;
22
23
use core::str::next_code_point;
23
24
24
25
use crate::borrow::Cow;
25
26
use crate::collections::TryReserveError;
26
27
use crate::hash::{Hash, Hasher};
27
28
use crate::iter::FusedIterator;
29
+ use crate::ptr::addr_of_mut;
28
30
use crate::rc::Rc;
29
31
use crate::sync::Arc;
30
32
use crate::sys_common::AsInner;
@@ -1046,3 +1048,12 @@ impl Hash for Wtf8 {
1046
1048
0xfeu8.hash(state)
1047
1049
}
1048
1050
}
1051
+
1052
+ #[unstable(feature = "clone_to_uninit", issue = "126799")]
1053
+ unsafe impl CloneToUninit for Wtf8 {
1054
+ #[cfg_attr(debug_assertions, track_caller)]
1055
+ unsafe fn clone_to_uninit(&self, dst: *mut Self) {
1056
+ // SAFETY: we're just a wrapper around [u8]
1057
+ unsafe { self.bytes.clone_to_uninit(addr_of_mut!((*dst).bytes)) }
1058
+ }
1059
+ }
You can’t perform that action at this time.
0 commit comments