@@ -334,15 +334,23 @@ pub unsafe trait FromZeroes {
334
334
where
335
335
Self : Sized ,
336
336
{
337
+ let size = mem:: size_of :: < Self > ( )
338
+ . checked_mul ( len)
339
+ . expect ( "mem::size_of::<Self>() * len overflows `usize`" ) ;
340
+ let align = mem:: align_of :: < Self > ( ) ;
341
+ // On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a
342
+ // bug in which sufficiently-large allocations (those which, when
343
+ // rounded up to the alignment, overflow `isize`) are not rejected,
344
+ // which can cause undefined behavior. See #64 for details.
345
+ //
346
+ // TODO(#67): Once our MSRV is > 1.64.0, remove this assertion.
347
+ #[ allow( clippy:: as_conversions) ]
348
+ let max_alloc = ( isize:: MAX as usize ) . saturating_sub ( align) ;
349
+ assert ! ( size <= max_alloc) ;
337
350
// TODO(#2): Use `Layout::repeat` when `alloc_layout_extra` is
338
351
// stabilized.
339
- let layout = Layout :: from_size_align (
340
- mem:: size_of :: < Self > ( )
341
- . checked_mul ( len)
342
- . expect ( "mem::size_of::<Self>() * len overflows `usize`" ) ,
343
- mem:: align_of :: < Self > ( ) ,
344
- )
345
- . expect ( "total allocation size overflows `isize`" ) ;
352
+ let layout =
353
+ Layout :: from_size_align ( size, align) . expect ( "total allocation size overflows `isize`" ) ;
346
354
347
355
// TODO(#61): Add a "SAFETY" comment and remove this `allow`.
348
356
#[ allow( clippy:: undocumented_unsafe_blocks) ]
@@ -1265,12 +1273,16 @@ impl<T> Unalign<T> {
1265
1273
/// If `self` does not satisfy `mem::align_of::<T>()`, then
1266
1274
/// `self.deref_unchecked()` may cause undefined behavior.
1267
1275
pub const unsafe fn deref_unchecked ( & self ) -> & T {
1268
- // SAFETY: `self.get_ptr()` returns a raw pointer to a valid `T` at the
1269
- // same memory location as `self`. It has no alignment guarantee, but
1270
- // the caller has promised that `self` is properly aligned, so we know
1271
- // that the pointer itself is aligned, and thus that it is sound to
1272
- // create a reference to a `T` at this memory location.
1273
- unsafe { & * self . get_ptr ( ) }
1276
+ // SAFETY: `Unalign<T>` is `repr(transparent)`, so there is a valid `T`
1277
+ // at the same memory location as `self`. It has no alignment guarantee,
1278
+ // but the caller has promised that `self` is properly aligned, so we
1279
+ // know that it is sound to create a reference to `T` at this memory
1280
+ // location.
1281
+ //
1282
+ // We use `mem::transmute` instead of `&*self.get_ptr()` because
1283
+ // dereferencing pointers is not stable in `const` on our current MSRV
1284
+ // (1.56 as of this writing).
1285
+ unsafe { mem:: transmute ( self ) }
1274
1286
}
1275
1287
1276
1288
/// Returns a mutable reference to the wrapped `T` without checking
@@ -1518,6 +1530,10 @@ macro_rules! transmute {
1518
1530
// were to use `core::mem::transmute`, this macro would not work in
1519
1531
// `std` contexts in which `core` was not manually imported. This is
1520
1532
// not a problem for 2018 edition crates.
1533
+ //
1534
+ // Some older versions of Clippy have a bug in which they don't
1535
+ // recognize the preceding safety comment.
1536
+ #[ allow( clippy:: undocumented_unsafe_blocks) ]
1521
1537
unsafe { $crate:: __real_transmute( e) }
1522
1538
}
1523
1539
} }
@@ -2782,17 +2798,12 @@ mod alloc_support {
2782
2798
2783
2799
#[ cfg( test) ]
2784
2800
mod tests {
2785
- use core:: convert:: TryFrom as _;
2786
-
2787
2801
use super :: * ;
2788
2802
2789
2803
#[ test]
2790
2804
fn test_extend_vec_zeroed ( ) {
2791
2805
// Test extending when there is an existing allocation.
2792
- let mut v: Vec < u64 > = Vec :: with_capacity ( 3 ) ;
2793
- v. push ( 100 ) ;
2794
- v. push ( 200 ) ;
2795
- v. push ( 300 ) ;
2806
+ let mut v = vec ! [ 100u64 , 200 , 300 ] ;
2796
2807
extend_vec_zeroed ( & mut v, 3 ) ;
2797
2808
assert_eq ! ( v. len( ) , 6 ) ;
2798
2809
assert_eq ! ( & * v, & [ 100 , 200 , 300 , 0 , 0 , 0 ] ) ;
@@ -2809,10 +2820,7 @@ mod alloc_support {
2809
2820
#[ test]
2810
2821
fn test_extend_vec_zeroed_zst ( ) {
2811
2822
// Test extending when there is an existing (fake) allocation.
2812
- let mut v: Vec < ( ) > = Vec :: with_capacity ( 3 ) ;
2813
- v. push ( ( ) ) ;
2814
- v. push ( ( ) ) ;
2815
- v. push ( ( ) ) ;
2823
+ let mut v = vec ! [ ( ) , ( ) , ( ) ] ;
2816
2824
extend_vec_zeroed ( & mut v, 3 ) ;
2817
2825
assert_eq ! ( v. len( ) , 6 ) ;
2818
2826
assert_eq ! ( & * v, & [ ( ) , ( ) , ( ) , ( ) , ( ) , ( ) ] ) ;
@@ -2835,30 +2843,21 @@ mod alloc_support {
2835
2843
drop ( v) ;
2836
2844
2837
2845
// Insert at start.
2838
- let mut v: Vec < u64 > = Vec :: with_capacity ( 3 ) ;
2839
- v. push ( 100 ) ;
2840
- v. push ( 200 ) ;
2841
- v. push ( 300 ) ;
2846
+ let mut v = vec ! [ 100u64 , 200 , 300 ] ;
2842
2847
insert_vec_zeroed ( & mut v, 0 , 2 ) ;
2843
2848
assert_eq ! ( v. len( ) , 5 ) ;
2844
2849
assert_eq ! ( & * v, & [ 0 , 0 , 100 , 200 , 300 ] ) ;
2845
2850
drop ( v) ;
2846
2851
2847
2852
// Insert at middle.
2848
- let mut v: Vec < u64 > = Vec :: with_capacity ( 3 ) ;
2849
- v. push ( 100 ) ;
2850
- v. push ( 200 ) ;
2851
- v. push ( 300 ) ;
2853
+ let mut v = vec ! [ 100u64 , 200 , 300 ] ;
2852
2854
insert_vec_zeroed ( & mut v, 1 , 1 ) ;
2853
2855
assert_eq ! ( v. len( ) , 4 ) ;
2854
2856
assert_eq ! ( & * v, & [ 100 , 0 , 200 , 300 ] ) ;
2855
2857
drop ( v) ;
2856
2858
2857
2859
// Insert at end.
2858
- let mut v: Vec < u64 > = Vec :: with_capacity ( 3 ) ;
2859
- v. push ( 100 ) ;
2860
- v. push ( 200 ) ;
2861
- v. push ( 300 ) ;
2860
+ let mut v = vec ! [ 100u64 , 200 , 300 ] ;
2862
2861
insert_vec_zeroed ( & mut v, 3 , 1 ) ;
2863
2862
assert_eq ! ( v. len( ) , 4 ) ;
2864
2863
assert_eq ! ( & * v, & [ 100 , 200 , 300 , 0 ] ) ;
@@ -2875,30 +2874,21 @@ mod alloc_support {
2875
2874
drop ( v) ;
2876
2875
2877
2876
// Insert at start.
2878
- let mut v: Vec < ( ) > = Vec :: with_capacity ( 3 ) ;
2879
- v. push ( ( ) ) ;
2880
- v. push ( ( ) ) ;
2881
- v. push ( ( ) ) ;
2877
+ let mut v = vec ! [ ( ) , ( ) , ( ) ] ;
2882
2878
insert_vec_zeroed ( & mut v, 0 , 2 ) ;
2883
2879
assert_eq ! ( v. len( ) , 5 ) ;
2884
2880
assert_eq ! ( & * v, & [ ( ) , ( ) , ( ) , ( ) , ( ) ] ) ;
2885
2881
drop ( v) ;
2886
2882
2887
2883
// Insert at middle.
2888
- let mut v: Vec < ( ) > = Vec :: with_capacity ( 3 ) ;
2889
- v. push ( ( ) ) ;
2890
- v. push ( ( ) ) ;
2891
- v. push ( ( ) ) ;
2884
+ let mut v = vec ! [ ( ) , ( ) , ( ) ] ;
2892
2885
insert_vec_zeroed ( & mut v, 1 , 1 ) ;
2893
2886
assert_eq ! ( v. len( ) , 4 ) ;
2894
2887
assert_eq ! ( & * v, & [ ( ) , ( ) , ( ) , ( ) ] ) ;
2895
2888
drop ( v) ;
2896
2889
2897
2890
// Insert at end.
2898
- let mut v: Vec < ( ) > = Vec :: with_capacity ( 3 ) ;
2899
- v. push ( ( ) ) ;
2900
- v. push ( ( ) ) ;
2901
- v. push ( ( ) ) ;
2891
+ let mut v = vec ! [ ( ) , ( ) , ( ) ] ;
2902
2892
insert_vec_zeroed ( & mut v, 3 , 1 ) ;
2903
2893
assert_eq ! ( v. len( ) , 4 ) ;
2904
2894
assert_eq ! ( & * v, & [ ( ) , ( ) , ( ) , ( ) ] ) ;
@@ -2967,7 +2957,7 @@ mod alloc_support {
2967
2957
}
2968
2958
2969
2959
#[ test]
2970
- #[ should_panic( expected = "total allocation size overflows `isize`: LayoutError " ) ]
2960
+ #[ should_panic( expected = "assertion failed: size <= max_alloc " ) ]
2971
2961
fn test_new_box_slice_zeroed_panics_isize_overflow ( ) {
2972
2962
let max = usize:: try_from ( isize:: MAX ) . unwrap ( ) ;
2973
2963
let _ = u16:: new_box_slice_zeroed ( ( max / mem:: size_of :: < u16 > ( ) ) + 1 ) ;
@@ -3758,7 +3748,7 @@ mod tests {
3758
3748
/// has had its bits flipped (by applying `^= 0xFF`).
3759
3749
///
3760
3750
/// `N` is the size of `t` in bytes.
3761
- fn test < const N : usize , T : FromBytes + AsBytes + Debug + Eq + ?Sized > (
3751
+ fn test < T : FromBytes + AsBytes + Debug + Eq + ?Sized , const N : usize > (
3762
3752
t : & mut T ,
3763
3753
bytes : & [ u8 ] ,
3764
3754
post_mutation : & T ,
@@ -3830,12 +3820,12 @@ mod tests {
3830
3820
} ;
3831
3821
let post_mutation_expected_a =
3832
3822
if cfg ! ( target_endian = "little" ) { 0x00_00_00_FE } else { 0xFF_00_00_01 } ;
3833
- test :: < 12 , _ > (
3823
+ test :: < _ , 12 > (
3834
3824
& mut Foo { a : 1 , b : Wrapping ( 2 ) , c : None } ,
3835
3825
expected_bytes. as_bytes ( ) ,
3836
3826
& Foo { a : post_mutation_expected_a, b : Wrapping ( 2 ) , c : None } ,
3837
3827
) ;
3838
- test :: < 3 , _ > (
3828
+ test :: < _ , 3 > (
3839
3829
Unsized :: from_mut_slice ( & mut [ 1 , 2 , 3 ] ) ,
3840
3830
& [ 1 , 2 , 3 ] ,
3841
3831
Unsized :: from_mut_slice ( & mut [ 0xFE , 2 , 3 ] ) ,
0 commit comments