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 ;
@@ -1266,6 +1269,15 @@ impl Clone for Box<OsStr> {
1266
1269
}
1267
1270
}
1268
1271
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
+
1269
1281
#[ stable( feature = "shared_from_slice2" , since = "1.24.0" ) ]
1270
1282
impl From < OsString > for Arc < OsStr > {
1271
1283
/// 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 ;
@@ -3022,6 +3024,15 @@ impl Path {
3022
3024
}
3023
3025
}
3024
3026
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
+
3025
3036
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3026
3037
impl AsRef < OsStr > for Path {
3027
3038
#[ 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;
@@ -347,3 +350,12 @@ impl Slice {
347
350
self . inner . eq_ignore_ascii_case ( & other. inner )
348
351
}
349
352
}
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 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 ;
@@ -270,3 +272,12 @@ impl Slice {
270
272
self . inner . eq_ignore_ascii_case ( & other. inner )
271
273
}
272
274
}
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 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