12
12
use crate :: distr:: uniform:: { SampleRange , SampleUniform } ;
13
13
use crate :: distr:: { self , Distribution , StandardUniform } ;
14
14
use core:: num:: Wrapping ;
15
+ use core:: { mem, slice} ;
15
16
use rand_core:: RngCore ;
16
- use zerocopy:: IntoBytes ;
17
17
18
18
/// User-level interface for RNGs
19
19
///
@@ -393,13 +393,20 @@ impl Fill for [u8] {
393
393
}
394
394
}
395
395
396
- macro_rules! impl_fill {
396
+ // This macro is unsafe to call: target types must support transmute from
397
+ // random bits (i.e. all bit representations are valid).
398
+ macro_rules! unsafe_impl_fill {
397
399
( ) => { } ;
398
400
( $t: ty) => {
399
401
impl Fill for [ $t] {
400
402
fn fill<R : Rng + ?Sized >( & mut self , rng: & mut R ) {
401
403
if self . len( ) > 0 {
402
- rng. fill_bytes( self . as_mut_bytes( ) ) ;
404
+ rng. fill_bytes( unsafe {
405
+ slice:: from_raw_parts_mut( self . as_mut_ptr( )
406
+ as * mut u8 ,
407
+ mem:: size_of_val( self )
408
+ )
409
+ } ) ;
403
410
for x in self {
404
411
* x = x. to_le( ) ;
405
412
}
@@ -410,24 +417,29 @@ macro_rules! impl_fill {
410
417
impl Fill for [ Wrapping <$t>] {
411
418
fn fill<R : Rng + ?Sized >( & mut self , rng: & mut R ) {
412
419
if self . len( ) > 0 {
413
- rng. fill_bytes( self . as_mut_bytes( ) ) ;
420
+ rng. fill_bytes( unsafe {
421
+ slice:: from_raw_parts_mut( self . as_mut_ptr( )
422
+ as * mut u8 ,
423
+ self . len( ) * mem:: size_of:: <$t>( )
424
+ )
425
+ } ) ;
414
426
for x in self {
415
- * x = Wrapping ( x. 0 . to_le( ) ) ;
427
+ * x = Wrapping ( x. 0 . to_le( ) ) ;
416
428
}
417
429
}
418
430
}
419
431
}
420
432
} ;
421
433
( $t: ty, $( $tt: ty, ) * ) => {
422
- impl_fill !( $t) ;
434
+ unsafe_impl_fill !( $t) ;
423
435
// TODO: this could replace above impl once Rust #32463 is fixed
424
- // impl_fill !(Wrapping<$t>);
425
- impl_fill !( $( $tt, ) * ) ;
436
+ // unsafe_impl_fill !(Wrapping<$t>);
437
+ unsafe_impl_fill !( $( $tt, ) * ) ;
426
438
}
427
439
}
428
440
429
- impl_fill ! ( u16 , u32 , u64 , u128 , ) ;
430
- impl_fill ! ( i8 , i16 , i32 , i64 , i128 , ) ;
441
+ unsafe_impl_fill ! ( u16 , u32 , u64 , u128 , ) ;
442
+ unsafe_impl_fill ! ( i8 , i16 , i32 , i64 , i128 , ) ;
431
443
432
444
impl < T , const N : usize > Fill for [ T ; N ]
433
445
where
0 commit comments