@@ -72,6 +72,9 @@ impl Layout {
72
72
#[ inline]
73
73
#[ rustc_allow_const_fn_unstable( ptr_alignment_type) ]
74
74
#[ ensures( |result| result. is_err( ) || align. is_power_of_two( ) ) ]
75
+ #[ ensures( |result| result. is_err( ) || size <= isize :: MAX as usize - ( align - 1 ) ) ]
76
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . size( ) == size) ]
77
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . align( ) == align) ]
75
78
pub const fn from_size_align ( size : usize , align : usize ) -> Result < Self , LayoutError > {
76
79
if !align. is_power_of_two ( ) {
77
80
return Err ( LayoutError ) ;
@@ -123,6 +126,8 @@ impl Layout {
123
126
#[ inline]
124
127
#[ rustc_allow_const_fn_unstable( ptr_alignment_type) ]
125
128
#[ requires( Layout :: from_size_align( size, align) . is_ok( ) ) ]
129
+ #[ ensures( |result| result. size( ) == size) ]
130
+ #[ ensures( |result| result. align( ) == align) ]
126
131
pub const unsafe fn from_size_align_unchecked ( size : usize , align : usize ) -> Self {
127
132
// SAFETY: the caller is required to uphold the preconditions.
128
133
unsafe { Layout { size, align : Alignment :: new_unchecked ( align) } }
@@ -247,6 +252,7 @@ impl Layout {
247
252
#[ stable( feature = "alloc_layout_manipulation" , since = "1.44.0" ) ]
248
253
#[ inline]
249
254
#[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . align( ) >= align) ]
255
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . align( ) . is_power_of_two( ) ) ]
250
256
pub fn align_to ( & self , align : usize ) -> Result < Self , LayoutError > {
251
257
Layout :: from_size_align ( self . size ( ) , cmp:: max ( self . align ( ) , align) )
252
258
}
@@ -309,7 +315,10 @@ impl Layout {
309
315
#[ must_use = "this returns a new `Layout`, \
310
316
without modifying the original"]
311
317
#[ inline]
318
+ #[ ensures( |result| result. size( ) >= self . size( ) ) ]
319
+ #[ ensures( |result| result. align( ) == self . align( ) ) ]
312
320
#[ ensures( |result| result. size( ) % result. align( ) == 0 ) ]
321
+ #[ ensures( |result| self . size( ) + self . padding_needed_for( self . align( ) ) == result. size( ) ) ]
313
322
pub const fn pad_to_align ( & self ) -> Layout {
314
323
let pad = self . padding_needed_for ( self . align ( ) ) ;
315
324
// This cannot overflow. Quoting from the invariant of Layout:
@@ -332,7 +341,9 @@ impl Layout {
332
341
/// On arithmetic overflow, returns `LayoutError`.
333
342
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
334
343
#[ inline]
335
- #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . 1 % n == 0 ) ]
344
+ #[ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 1 % n == 0 ) ]
345
+ #[ ensures( |result| result. is_err( ) || n == 0 || result. as_ref( ) . unwrap( ) . 0 . size( ) >= self . size( ) ) ]
346
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . 0 . size( ) == n * result. as_ref( ) . unwrap( ) . 1 ) ]
336
347
pub fn repeat ( & self , n : usize ) -> Result < ( Self , usize ) , LayoutError > {
337
348
// This cannot overflow. Quoting from the invariant of Layout:
338
349
// > `size`, when rounded up to the nearest multiple of `align`,
@@ -393,6 +404,9 @@ impl Layout {
393
404
/// ```
394
405
#[ stable( feature = "alloc_layout_manipulation" , since = "1.44.0" ) ]
395
406
#[ inline]
407
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . 0 . align( ) == cmp:: max( self . align( ) , next. align( ) ) ) ]
408
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . 0 . size( ) >= self . size( ) + next. size( ) ) ]
409
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . 1 >= self . size( ) ) ]
396
410
#[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . 1 <= result. as_ref( ) . unwrap( ) . 0 . size( ) ) ]
397
411
pub fn extend ( & self , next : Self ) -> Result < ( Self , usize ) , LayoutError > {
398
412
let new_align = cmp:: max ( self . align , next. align ) ;
@@ -420,7 +434,8 @@ impl Layout {
420
434
/// On arithmetic overflow, returns `LayoutError`.
421
435
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
422
436
#[ inline]
423
- #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . size( ) % n == 0 ) ]
437
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . size( ) == n * self . size( ) ) ]
438
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . align( ) == self . align( ) ) ]
424
439
pub fn repeat_packed ( & self , n : usize ) -> Result < Self , LayoutError > {
425
440
let size = self . size ( ) . checked_mul ( n) . ok_or ( LayoutError ) ?;
426
441
// The safe constructor is called here to enforce the isize size limit.
@@ -435,7 +450,11 @@ impl Layout {
435
450
/// On arithmetic overflow, returns `LayoutError`.
436
451
#[ unstable( feature = "alloc_layout_extra" , issue = "55724" ) ]
437
452
#[ inline]
453
+ // the below is wrong but was written in a previous commit; keeping it for now to confirm that
454
+ // this is caught
438
455
#[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . size( ) <= next. size( ) ) ]
456
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . size( ) == self . size( ) + next. size( ) ) ]
457
+ #[ ensures( |result| result. is_err( ) || result. as_ref( ) . unwrap( ) . align( ) == self . align( ) ) ]
439
458
pub fn extend_packed ( & self , next : Self ) -> Result < Self , LayoutError > {
440
459
let new_size = self . size ( ) . checked_add ( next. size ( ) ) . ok_or ( LayoutError ) ?;
441
460
// The safe constructor is called here to enforce the isize size limit.
@@ -520,26 +539,16 @@ mod verify {
520
539
pub fn check_from_size_align ( ) {
521
540
let s = kani:: any :: < usize > ( ) ;
522
541
let a = kani:: any :: < usize > ( ) ;
523
-
524
- if let Ok ( layout) = Layout :: from_size_align ( s, a) {
525
- assert_eq ! ( layout. size( ) , s) ;
526
- assert_eq ! ( layout. align( ) , a) ;
527
- assert ! ( a > 0 ) ;
528
- assert ! ( a. is_power_of_two( ) ) ;
529
- assert ! ( s <= isize :: MAX as usize - ( a - 1 ) ) ;
530
- }
542
+ let _ = Layout :: from_size_align ( s, a) ;
531
543
}
532
544
533
545
// pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self
534
546
#[ kani:: proof_for_contract( Layout :: from_size_align_unchecked) ]
535
547
pub fn check_from_size_align_unchecked ( ) {
536
548
let s = kani:: any :: < usize > ( ) ;
537
549
let a = kani:: any :: < usize > ( ) ;
538
-
539
550
unsafe {
540
- let layout = Layout :: from_size_align_unchecked ( s, a) ;
541
- assert_eq ! ( layout. size( ) , s) ;
542
- assert_eq ! ( layout. align( ) , a) ;
551
+ let _ = Layout :: from_size_align_unchecked ( s, a) ;
543
552
}
544
553
}
545
554
@@ -548,7 +557,6 @@ mod verify {
548
557
pub fn check_size ( ) {
549
558
let s = kani:: any :: < usize > ( ) ;
550
559
let a = kani:: any :: < usize > ( ) ;
551
-
552
560
unsafe {
553
561
let layout = Layout :: from_size_align_unchecked ( s, a) ;
554
562
assert_eq ! ( layout. size( ) , s) ;
@@ -560,10 +568,9 @@ mod verify {
560
568
pub fn check_align ( ) {
561
569
let s = kani:: any :: < usize > ( ) ;
562
570
let a = kani:: any :: < usize > ( ) ;
563
-
564
571
unsafe {
565
572
let layout = Layout :: from_size_align_unchecked ( s, a) ;
566
- assert ! ( layout. align( ) . is_power_of_two ( ) ) ;
573
+ let _ = layout. align ( ) ;
567
574
}
568
575
}
569
576
@@ -579,16 +586,14 @@ mod verify {
579
586
#[ kani:: proof_for_contract( Layout :: for_value) ]
580
587
pub fn check_for_value_i32 ( ) {
581
588
let array : [ i32 ; 2 ] = [ 1 , 2 ] ;
582
- let layout = Layout :: for_value :: < [ i32 ] > ( & array[ 1 .. 1 ] ) ;
583
- assert ! ( layout. align( ) . is_power_of_two( ) ) ;
589
+ let _ = Layout :: for_value :: < [ i32 ] > ( & array[ 1 .. 1 ] ) ;
584
590
}
585
591
586
592
// pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self
587
593
#[ kani:: proof_for_contract( Layout :: for_value_raw) ]
588
594
pub fn check_for_value_raw_i32 ( ) {
589
595
unsafe {
590
- let layout = Layout :: for_value_raw :: < [ i32 ] > ( & [ ] as * const [ i32 ] ) ;
591
- assert ! ( layout. align( ) . is_power_of_two( ) ) ;
596
+ let _ = Layout :: for_value_raw :: < [ i32 ] > ( & [ ] as * const [ i32 ] ) ;
592
597
}
593
598
}
594
599
@@ -597,10 +602,9 @@ mod verify {
597
602
pub fn check_dangling ( ) {
598
603
let s = kani:: any :: < usize > ( ) ;
599
604
let a = kani:: any :: < usize > ( ) ;
600
-
601
605
unsafe {
602
606
let layout = Layout :: from_size_align_unchecked ( s, a) ;
603
- assert ! ( layout. dangling( ) . is_aligned ( ) ) ;
607
+ let _ = layout. dangling ( ) ;
604
608
}
605
609
}
606
610
@@ -609,14 +613,10 @@ mod verify {
609
613
pub fn check_align_to ( ) {
610
614
let s = kani:: any :: < usize > ( ) ;
611
615
let a = kani:: any :: < usize > ( ) ;
612
-
613
616
unsafe {
614
617
let layout = Layout :: from_size_align_unchecked ( s, a) ;
615
618
let a2 = kani:: any :: < usize > ( ) ;
616
- if let Ok ( layout2) = layout. align_to ( a2) {
617
- assert ! ( layout2. align( ) > 0 ) ;
618
- assert ! ( layout2. align( ) . is_power_of_two( ) ) ;
619
- }
619
+ let _ = layout. align_to ( a2) ;
620
620
}
621
621
}
622
622
@@ -625,13 +625,11 @@ mod verify {
625
625
pub fn check_padding_needed_for ( ) {
626
626
let s = kani:: any :: < usize > ( ) ;
627
627
let a = kani:: any :: < usize > ( ) ;
628
-
629
628
unsafe {
630
629
let layout = Layout :: from_size_align_unchecked ( s, a) ;
631
630
let a2 = kani:: any :: < usize > ( ) ;
632
631
if ( a2. is_power_of_two ( ) && a2 <= a) {
633
- let p = layout. padding_needed_for ( a2) ;
634
- assert ! ( p <= a2) ;
632
+ let _ = layout. padding_needed_for ( a2) ;
635
633
}
636
634
}
637
635
}
@@ -641,12 +639,9 @@ mod verify {
641
639
pub fn check_pad_to_align ( ) {
642
640
let s = kani:: any :: < usize > ( ) ;
643
641
let a = kani:: any :: < usize > ( ) ;
644
-
645
642
unsafe {
646
643
let layout = Layout :: from_size_align_unchecked ( s, a) ;
647
- let layout2 = layout. pad_to_align ( ) ;
648
- assert_eq ! ( layout2. size( ) % a, 0 ) ;
649
- assert_eq ! ( layout. size( ) + layout. padding_needed_for( layout. align( ) ) , layout2. size( ) ) ;
644
+ let _ = layout. pad_to_align ( ) ;
650
645
}
651
646
}
652
647
@@ -655,14 +650,10 @@ mod verify {
655
650
pub fn check_repeat ( ) {
656
651
let s = kani:: any :: < usize > ( ) ;
657
652
let a = kani:: any :: < usize > ( ) ;
658
-
659
653
unsafe {
660
654
let layout = Layout :: from_size_align_unchecked ( s, a) ;
661
655
let n = kani:: any :: < usize > ( ) ;
662
- if let Ok ( ( layout2, padded_size) ) = layout. repeat ( n) {
663
- assert ! ( n == 0 || layout2. size( ) >= s) ;
664
- assert_eq ! ( layout2. size( ) , n * padded_size) ;
665
- }
656
+ let _ = layout. repeat ( n) ;
666
657
}
667
658
}
668
659
@@ -671,18 +662,12 @@ mod verify {
671
662
pub fn check_extend ( ) {
672
663
let s = kani:: any :: < usize > ( ) ;
673
664
let a = kani:: any :: < usize > ( ) ;
674
-
675
665
unsafe {
676
666
let layout = Layout :: from_size_align_unchecked ( s, a) ;
677
667
let s2 = kani:: any :: < usize > ( ) ;
678
668
let a2 = kani:: any :: < usize > ( ) ;
679
669
let layout2 = Layout :: from_size_align_unchecked ( s2, a2) ;
680
- if let Ok ( ( layout3, offset) ) = layout. extend ( layout2) {
681
- assert_eq ! ( layout3. align( ) , cmp:: max( a, a2) ) ;
682
- assert ! ( layout3. size( ) >= s + s2) ;
683
- assert ! ( offset >= s) ;
684
- assert ! ( offset <= layout3. size( ) ) ;
685
- }
670
+ let _ = layout. extend ( layout2) ;
686
671
}
687
672
}
688
673
@@ -691,13 +676,10 @@ mod verify {
691
676
pub fn check_repeat_packed ( ) {
692
677
let s = kani:: any :: < usize > ( ) ;
693
678
let a = kani:: any :: < usize > ( ) ;
694
-
695
679
unsafe {
696
680
let layout = Layout :: from_size_align_unchecked ( s, a) ;
697
681
let n = kani:: any :: < usize > ( ) ;
698
- if let Ok ( layout2) = layout. repeat_packed ( n) {
699
- assert ! ( n == 0 || layout2. size( ) >= s) ;
700
- }
682
+ let _ = layout. repeat_packed ( n) ;
701
683
}
702
684
}
703
685
@@ -706,16 +688,12 @@ mod verify {
706
688
pub fn check_extend_packed ( ) {
707
689
let s = kani:: any :: < usize > ( ) ;
708
690
let a = kani:: any :: < usize > ( ) ;
709
-
710
691
unsafe {
711
692
let layout = Layout :: from_size_align_unchecked ( s, a) ;
712
693
let s2 = kani:: any :: < usize > ( ) ;
713
694
let a2 = kani:: any :: < usize > ( ) ;
714
695
let layout2 = Layout :: from_size_align_unchecked ( s2, a2) ;
715
- if let Ok ( layout3) = layout. extend_packed ( layout2) {
716
- assert_eq ! ( layout3. align( ) , a) ;
717
- assert_eq ! ( layout3. size( ) , s + s2) ;
718
- }
696
+ let _ = layout. extend_packed ( layout2) ;
719
697
}
720
698
}
721
699
0 commit comments