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 :: collections:: TryReserveError ;
810use crate :: hash:: { Hash , Hasher } ;
911use crate :: ops:: { self , Range } ;
12+ use crate :: ptr:: addr_of_mut;
1013use crate :: rc:: Rc ;
1114use crate :: str:: FromStr ;
1215use crate :: sync:: Arc ;
@@ -1261,6 +1264,15 @@ impl Clone for Box<OsStr> {
12611264 }
12621265}
12631266
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+
12641276#[ stable( feature = "shared_from_slice2" , since = "1.24.0" ) ]
12651277impl From < OsString > for Arc < OsStr > {
12661278 /// 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 :: * ;
2+ use crate :: mem:: MaybeUninit ;
3+ use crate :: ptr;
24
35#[ test]
46fn test_os_string_with_capacity ( ) {
@@ -286,3 +288,18 @@ fn slice_surrogate_edge() {
286288 assert_eq ! ( post_crab. slice_encoded_bytes( ..4 ) , "🦀" ) ;
287289 assert_eq ! ( post_crab. slice_encoded_bytes( 4 ..) , surrogate) ;
288290}
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 323323// tidy-alphabetical-start
324324#![ feature( c_str_module) ]
325325#![ feature( char_internals) ]
326+ #![ feature( clone_to_uninit) ]
326327#![ feature( core_intrinsics) ]
327328#![ feature( core_io_borrowed_buf) ]
328329#![ 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 :: collections:: TryReserveError ;
7577use crate :: error:: Error ;
@@ -3109,6 +3111,15 @@ impl Path {
31093111 }
31103112}
31113113
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+
31123123#[ stable( feature = "rust1" , since = "1.0.0" ) ]
31133124impl AsRef < OsStr > for Path {
31143125 #[ inline]
Original file line number Diff line number Diff line change @@ -3,6 +3,8 @@ use core::hint::black_box;
33use super :: * ;
44use crate :: collections:: { BTreeSet , HashSet } ;
55use crate :: hash:: DefaultHasher ;
6+ use crate :: mem:: MaybeUninit ;
7+ use crate :: ptr;
68
79#[ allow( unknown_lints, unused_macro_rules) ]
810macro_rules! t (
@@ -2054,3 +2056,20 @@ fn bench_hash_path_long(b: &mut test::Bencher) {
20542056
20552057 black_box ( hasher. finish ( ) ) ;
20562058}
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 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:: Write ;
@@ -345,3 +348,12 @@ impl Slice {
345348 self . inner . eq_ignore_ascii_case ( & other. inner )
346349 }
347350}
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 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;
5+
36use crate :: borrow:: Cow ;
47use crate :: collections:: TryReserveError ;
58use crate :: rc:: Rc ;
@@ -268,3 +271,12 @@ impl Slice {
268271 self . inner . eq_ignore_ascii_case ( & other. inner )
269272 }
270273}
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 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 ;
2526use crate :: collections:: TryReserveError ;
2627use crate :: hash:: { Hash , Hasher } ;
2728use crate :: iter:: FusedIterator ;
29+ use crate :: ptr:: addr_of_mut;
2830use crate :: rc:: Rc ;
2931use crate :: sync:: Arc ;
3032use crate :: sys_common:: AsInner ;
@@ -1046,3 +1048,12 @@ impl Hash for Wtf8 {
10461048 0xfeu8 . hash ( state)
10471049 }
10481050}
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