File tree 8 files changed +95
-0
lines changed
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