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 :: cmp;
8
10
use crate :: collections:: TryReserveError ;
9
11
use crate :: fmt;
10
12
use crate :: hash:: { Hash , Hasher } ;
11
13
use crate :: ops:: { self , Range } ;
14
+ use crate :: ptr:: addr_of_mut;
12
15
use crate :: rc:: Rc ;
13
16
use crate :: slice;
14
17
use crate :: str:: FromStr ;
@@ -1256,6 +1259,15 @@ impl Clone for Box<OsStr> {
1256
1259
}
1257
1260
}
1258
1261
1262
+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
1263
+ unsafe impl CloneToUninit for OsStr {
1264
+ #[ cfg_attr( debug_assertions, track_caller) ]
1265
+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
1266
+ // SAFETY: we're just a wrapper around a platform-specific Slice
1267
+ unsafe { self . inner . clone_to_uninit ( addr_of_mut ! ( ( * dst) . inner) ) }
1268
+ }
1269
+ }
1270
+
1259
1271
#[ stable( feature = "shared_from_slice2" , since = "1.24.0" ) ]
1260
1272
impl From < OsString > for Arc < OsStr > {
1261
1273
/// 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
2
3
+ use crate :: mem:: MaybeUninit ;
4
+ use crate :: ptr;
5
+
3
6
#[ test]
4
7
fn test_os_string_with_capacity ( ) {
5
8
let os_string = OsString :: with_capacity ( 0 ) ;
@@ -286,3 +289,18 @@ fn slice_surrogate_edge() {
286
289
assert_eq ! ( post_crab. slice_encoded_bytes( ..4 ) , "🦀" ) ;
287
290
assert_eq ! ( post_crab. slice_encoded_bytes( 4 ..) , surrogate) ;
288
291
}
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 319
319
// tidy-alphabetical-start
320
320
#![ feature( c_str_module) ]
321
321
#![ feature( char_internals) ]
322
+ #![ feature( clone_to_uninit) ]
322
323
#![ feature( core_intrinsics) ]
323
324
#![ feature( core_io_borrowed_buf) ]
324
325
#![ 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 :: cmp;
75
77
use crate :: collections:: TryReserveError ;
@@ -3027,6 +3029,15 @@ impl Path {
3027
3029
}
3028
3030
}
3029
3031
3032
+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
3033
+ unsafe impl CloneToUninit for Path {
3034
+ #[ cfg_attr( debug_assertions, track_caller) ]
3035
+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
3036
+ // SAFETY: Path is just a wrapper around OsStr
3037
+ unsafe { self . inner . clone_to_uninit ( core:: ptr:: addr_of_mut!( ( * dst) . inner) ) }
3038
+ }
3039
+ }
3040
+
3030
3041
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3031
3042
impl AsRef < OsStr > for Path {
3032
3043
#[ inline]
Original file line number Diff line number Diff line change @@ -2,6 +2,8 @@ use super::*;
2
2
3
3
use crate :: collections:: { BTreeSet , HashSet } ;
4
4
use crate :: hash:: DefaultHasher ;
5
+ use crate :: mem:: MaybeUninit ;
6
+ use crate :: ptr;
5
7
use core:: hint:: black_box;
6
8
7
9
#[ allow( unknown_lints, unused_macro_rules) ]
@@ -1945,3 +1947,20 @@ fn bench_hash_path_long(b: &mut test::Bencher) {
1945
1947
1946
1948
black_box ( hasher. finish ( ) ) ;
1947
1949
}
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 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;
@@ -337,3 +340,12 @@ impl Slice {
337
340
self . inner . eq_ignore_ascii_case ( & other. inner )
338
341
}
339
342
}
343
+
344
+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
345
+ unsafe impl CloneToUninit for Slice {
346
+ #[ cfg_attr( debug_assertions, track_caller) ]
347
+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
348
+ // SAFETY: we're just a wrapper around [u8]
349
+ unsafe { self . inner . clone_to_uninit ( addr_of_mut ! ( ( * dst) . inner) ) }
350
+ }
351
+ }
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;
3
5
4
6
use crate :: borrow:: Cow ;
5
7
use crate :: collections:: TryReserveError ;
@@ -260,3 +262,12 @@ impl Slice {
260
262
self . inner . eq_ignore_ascii_case ( & other. inner )
261
263
}
262
264
}
265
+
266
+ #[ unstable( feature = "clone_to_uninit" , issue = "126799" ) ]
267
+ unsafe impl CloneToUninit for Slice {
268
+ #[ cfg_attr( debug_assertions, track_caller) ]
269
+ unsafe fn clone_to_uninit ( & self , dst : * mut Self ) {
270
+ // SAFETY: we're just a wrapper around Wtf8
271
+ unsafe { self . inner . clone_to_uninit ( addr_of_mut ! ( ( * dst) . inner) ) }
272
+ }
273
+ }
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 ;
@@ -28,6 +29,7 @@ use crate::hash::{Hash, Hasher};
28
29
use crate :: iter:: FusedIterator ;
29
30
use crate :: mem;
30
31
use crate :: ops;
32
+ use crate :: ptr:: addr_of_mut;
31
33
use crate :: rc:: Rc ;
32
34
use crate :: slice;
33
35
use crate :: str;
@@ -1044,3 +1046,12 @@ impl Hash for Wtf8 {
1044
1046
0xfeu8 . hash ( state)
1045
1047
}
1046
1048
}
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