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 33#[ cfg( test) ]
44mod tests;
55
6+ use core:: clone:: CloneToUninit ;
7+
68use crate :: borrow:: { Borrow , Cow } ;
79use crate :: cmp;
810use crate :: collections:: TryReserveError ;
911use crate :: fmt;
1012use crate :: hash:: { Hash , Hasher } ;
1113use crate :: ops:: { self , Range } ;
14+ use crate :: ptr:: addr_of_mut;
1215use crate :: rc:: Rc ;
1316use crate :: slice;
1417use crate :: str:: FromStr ;
@@ -1266,6 +1269,15 @@ impl Clone for Box<OsStr> {
12661269 }
12671270}
12681271
1272+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
1273+ unsafe impl CloneToUninit for OsStr {
1274+ #[ cfg_attr( debug_assertions, track_caller) ]
1275+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
1276+ // SAFETY: we're just a wrapper around a platform-specific Slice
1277+ unsafe { self . inner . clone_to_uninit ( addr_of_mut ! ( ( * dst) . inner) ) }
1278+ }
1279+ }
1280+
12691281#[ stable( feature = "shared_from_slice2" , since = "1.24.0" ) ]
12701282impl From < OsString > for Arc < OsStr > {
12711283 /// Converts an [`OsString`] into an <code>[Arc]<[OsStr]></code> by moving the [`OsString`]
Original file line number Diff line number Diff line change 11use super :: * ;
22
3+ use crate :: mem:: MaybeUninit ;
4+ use crate :: ptr;
5+
36#[ test]
47fn test_os_string_with_capacity ( ) {
58 let os_string = OsString :: with_capacity ( 0 ) ;
@@ -286,3 +289,18 @@ fn slice_surrogate_edge() {
286289 assert_eq ! ( post_crab. slice_encoded_bytes( ..4 ) , "🦀" ) ;
287290 assert_eq ! ( post_crab. slice_encoded_bytes( 4 ..) , surrogate) ;
288291}
292+
293+ #[ test]
294+ fn clone_to_uninit ( ) {
295+ let a = OsStr :: new ( "hello.txt" ) ;
296+
297+ let mut storage = vec ! [ MaybeUninit :: <u8 >:: uninit( ) ; size_of_val:: <OsStr >( a) ] ;
298+ unsafe { a. clone_to_uninit ( ptr:: from_mut :: < [ _ ] > ( storage. as_mut_slice ( ) ) as * mut OsStr ) } ;
299+ assert_eq ! ( a. as_encoded_bytes( ) , unsafe { MaybeUninit :: slice_assume_init_ref( & storage) } ) ;
300+
301+ let mut b: Box < OsStr > = OsStr :: new ( "world.exe" ) . into ( ) ;
302+ assert_eq ! ( size_of_val:: <OsStr >( a) , size_of_val:: <OsStr >( & b) ) ;
303+ assert_ne ! ( a, & * b) ;
304+ unsafe { a. clone_to_uninit ( ptr:: from_mut :: < OsStr > ( & mut b) ) } ;
305+ assert_eq ! ( a, & * b) ;
306+ }
Original file line number Diff line number Diff line change 319319// tidy-alphabetical-start
320320#![ feature( c_str_module) ]
321321#![ feature( char_internals) ]
322+ #![ feature( clone_to_uninit) ]
322323#![ feature( core_intrinsics) ]
323324#![ feature( core_io_borrowed_buf) ]
324325#![ feature( duration_constants) ]
Original file line number Diff line number Diff line change 7070#[ cfg( test) ]
7171mod tests;
7272
73+ use core:: clone:: CloneToUninit ;
74+
7375use crate :: borrow:: { Borrow , Cow } ;
7476use crate :: cmp;
7577use crate :: collections:: TryReserveError ;
@@ -3022,6 +3024,15 @@ impl Path {
30223024 }
30233025}
30243026
3027+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
3028+ unsafe impl CloneToUninit for Path {
3029+ #[ cfg_attr( debug_assertions, track_caller) ]
3030+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
3031+ // SAFETY: Path is just a wrapper around OsStr
3032+ unsafe { self . inner . clone_to_uninit ( core:: ptr:: addr_of_mut!( ( * dst) . inner) ) }
3033+ }
3034+ }
3035+
30253036#[ stable( feature = "rust1" , since = "1.0.0" ) ]
30263037impl AsRef < OsStr > for Path {
30273038 #[ inline]
Original file line number Diff line number Diff line change @@ -2,6 +2,8 @@ use super::*;
22
33use crate :: collections:: { BTreeSet , HashSet } ;
44use crate :: hash:: DefaultHasher ;
5+ use crate :: mem:: MaybeUninit ;
6+ use crate :: ptr;
57use core:: hint:: black_box;
68
79#[ allow( unknown_lints, unused_macro_rules) ]
@@ -1945,3 +1947,20 @@ fn bench_hash_path_long(b: &mut test::Bencher) {
19451947
19461948 black_box ( hasher. finish ( ) ) ;
19471949}
1950+
1951+ #[ test]
1952+ fn clone_to_uninit ( ) {
1953+ let a = Path :: new ( "hello.txt" ) ;
1954+
1955+ let mut storage = vec ! [ MaybeUninit :: <u8 >:: uninit( ) ; size_of_val:: <Path >( a) ] ;
1956+ unsafe { a. clone_to_uninit ( ptr:: from_mut :: < [ _ ] > ( storage. as_mut_slice ( ) ) as * mut Path ) } ;
1957+ assert_eq ! ( a. as_os_str( ) . as_encoded_bytes( ) , unsafe {
1958+ MaybeUninit :: slice_assume_init_ref( & storage)
1959+ } ) ;
1960+
1961+ let mut b: Box < Path > = Path :: new ( "world.exe" ) . into ( ) ;
1962+ assert_eq ! ( size_of_val:: <Path >( a) , size_of_val:: <Path >( & b) ) ;
1963+ assert_ne ! ( a, & * b) ;
1964+ unsafe { a. clone_to_uninit ( ptr:: from_mut :: < Path > ( & mut b) ) } ;
1965+ assert_eq ! ( a, & * b) ;
1966+ }
Original file line number Diff line number Diff line change 11//! The underlying OsString/OsStr implementation on Unix and many other
22//! systems: just a `Vec<u8>`/`[u8]`.
33
4+ use core:: clone:: CloneToUninit ;
5+ use core:: ptr:: addr_of_mut;
6+
47use crate :: borrow:: Cow ;
58use crate :: collections:: TryReserveError ;
69use crate :: fmt;
@@ -347,3 +350,12 @@ impl Slice {
347350 self . inner . eq_ignore_ascii_case ( & other. inner )
348351 }
349352}
353+
354+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
355+ unsafe impl CloneToUninit for Slice {
356+ #[ cfg_attr( debug_assertions, track_caller) ]
357+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
358+ // SAFETY: we're just a wrapper around [u8]
359+ unsafe { self . inner . clone_to_uninit ( addr_of_mut ! ( ( * dst) . inner) ) }
360+ }
361+ }
Original file line number Diff line number Diff line change 11//! The underlying OsString/OsStr implementation on Windows is a
22//! wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
3+ use core:: clone:: CloneToUninit ;
4+ use core:: ptr:: addr_of_mut;
35
46use crate :: borrow:: Cow ;
57use crate :: collections:: TryReserveError ;
@@ -270,3 +272,12 @@ impl Slice {
270272 self . inner . eq_ignore_ascii_case ( & other. inner )
271273 }
272274}
275+
276+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
277+ unsafe impl CloneToUninit for Slice {
278+ #[ cfg_attr( debug_assertions, track_caller) ]
279+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
280+ // SAFETY: we're just a wrapper around Wtf8
281+ unsafe { self . inner . clone_to_uninit ( addr_of_mut ! ( ( * dst) . inner) ) }
282+ }
283+ }
Original file line number Diff line number Diff line change 1919mod tests;
2020
2121use core:: char:: { encode_utf16_raw, encode_utf8_raw} ;
22+ use core:: clone:: CloneToUninit ;
2223use core:: str:: next_code_point;
2324
2425use crate :: borrow:: Cow ;
@@ -28,6 +29,7 @@ use crate::hash::{Hash, Hasher};
2829use crate :: iter:: FusedIterator ;
2930use crate :: mem;
3031use crate :: ops;
32+ use crate :: ptr:: addr_of_mut;
3133use crate :: rc:: Rc ;
3234use crate :: slice;
3335use crate :: str;
@@ -1044,3 +1046,12 @@ impl Hash for Wtf8 {
10441046 0xfeu8 . hash ( state)
10451047 }
10461048}
1049+
1050+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
1051+ unsafe impl CloneToUninit for Wtf8 {
1052+ #[ cfg_attr( debug_assertions, track_caller) ]
1053+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
1054+ // SAFETY: we're just a wrapper around [u8]
1055+ unsafe { self . bytes . clone_to_uninit ( addr_of_mut ! ( ( * dst) . bytes) ) }
1056+ }
1057+ }
You can’t perform that action at this time.
0 commit comments