1- use safety:: requires;
1+ use safety:: { ensures , requires} ;
22use crate :: num:: NonZero ;
33#[ cfg( debug_assertions) ]
44use crate :: ub_checks:: assert_unsafe_precondition;
@@ -60,6 +60,7 @@ impl Alignment {
6060 #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
6161 #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
6262 #[ inline]
63+ #[ ensures( |result| align. is_power_of_two( ) == result. is_some( ) ) ]
6364 pub const fn new ( align : usize ) -> Option < Self > {
6465 if align. is_power_of_two ( ) {
6566 // SAFETY: Just checked it only has one bit set
@@ -81,6 +82,8 @@ impl Alignment {
8182 #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
8283 #[ inline]
8384 #[ requires( align > 0 && ( align & ( align - 1 ) ) == 0 ) ]
85+ #[ ensures( |result| result. as_usize( ) == align) ]
86+ #[ ensures( |result| result. as_usize( ) . is_power_of_two( ) ) ]
8487 pub const unsafe fn new_unchecked ( align : usize ) -> Self {
8588 #[ cfg( debug_assertions) ]
8689 assert_unsafe_precondition ! (
@@ -98,6 +101,7 @@ impl Alignment {
98101 #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
99102 #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
100103 #[ inline]
104+ #[ ensures( |result| result. is_power_of_two( ) ) ]
101105 pub const fn as_usize ( self ) -> usize {
102106 self . 0 as usize
103107 }
@@ -106,6 +110,7 @@ impl Alignment {
106110 #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
107111 #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
108112 #[ inline]
113+ #[ ensures( |result| result. get( ) . is_power_of_two( ) ) ]
109114 pub const fn as_nonzero ( self ) -> NonZero < usize > {
110115 // SAFETY: All the discriminants are non-zero.
111116 unsafe { NonZero :: new_unchecked ( self . as_usize ( ) ) }
@@ -127,6 +132,7 @@ impl Alignment {
127132 #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
128133 #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
129134 #[ inline]
135+ #[ ensures( |result| ( * result as usize ) < mem:: size_of:: <usize >( ) * 8 ) ]
130136 pub const fn log2 ( self ) -> u32 {
131137 self . as_nonzero ( ) . trailing_zeros ( )
132138 }
@@ -157,6 +163,7 @@ impl Alignment {
157163 #[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
158164 #[ rustc_const_unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
159165 #[ inline]
166+ #[ ensures( |result| * result > 0 ) ]
160167 pub const fn mask ( self ) -> usize {
161168 // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
162169 !( unsafe { self . as_usize ( ) . unchecked_sub ( 1 ) } )
@@ -375,14 +382,68 @@ enum AlignmentEnum {
375382mod verify {
376383 use super :: * ;
377384
385+ // pub const fn of<T>() -> Self
386+ #[ kani:: proof]
387+ pub fn check_of_i32 ( ) {
388+ let alignment = Alignment :: of :: < i32 > ( ) ;
389+ assert ! ( alignment. as_usize( ) . is_power_of_two( ) ) ;
390+ }
391+
392+ // pub const fn new(align: usize) -> Option<Self>
393+ #[ kani:: proof_for_contract( Alignment :: new) ]
394+ pub fn check_new ( ) {
395+ let a = kani:: any :: < usize > ( ) ;
396+ let alignment_opt = Alignment :: new ( a) ;
397+ match alignment_opt {
398+ Some ( alignment) => assert_eq ! ( alignment. as_usize( ) , a) ,
399+ None => assert ! ( !a. is_power_of_two( ) )
400+ }
401+ }
402+
403+ // pub const unsafe fn new_unchecked(align: usize) -> Self
378404 #[ kani:: proof_for_contract( Alignment :: new_unchecked) ]
379405 pub fn check_new_unchecked ( ) {
380406 let a = kani:: any :: < usize > ( ) ;
381407
382408 unsafe {
383409 let alignment = Alignment :: new_unchecked ( a) ;
410+ assert ! ( alignment. as_usize( ) > 0 ) ;
411+ }
412+ }
413+
414+ // pub const fn as_usize(self) -> usize
415+ #[ kani:: proof_for_contract( Alignment :: as_usize) ]
416+ pub fn check_as_usize ( ) {
417+ let a = kani:: any :: < usize > ( ) ;
418+ if let Some ( alignment) = Alignment :: new ( a) {
384419 assert_eq ! ( alignment. as_usize( ) , a) ;
385- assert ! ( a. is_power_of_two( ) ) ;
420+ }
421+ }
422+
423+ // pub const fn as_nonzero(self) -> NonZero<usize>
424+ #[ kani:: proof_for_contract( Alignment :: as_nonzero) ]
425+ pub fn check_as_nonzero ( ) {
426+ let a = kani:: any :: < usize > ( ) ;
427+ if let Some ( alignment) = Alignment :: new ( a) {
428+ assert_eq ! ( alignment. as_nonzero( ) . get( ) , a) ;
429+ }
430+ }
431+
432+ // pub const fn log2(self) -> u32
433+ #[ kani:: proof_for_contract( Alignment :: log2) ]
434+ pub fn check_log2 ( ) {
435+ let a = kani:: any :: < usize > ( ) ;
436+ if let Some ( alignment) = Alignment :: new ( a) {
437+ assert_eq ! ( 1usize << alignment. log2( ) , a) ;
438+ }
439+ }
440+
441+ // pub const fn mask(self) -> usize
442+ #[ kani:: proof_for_contract( Alignment :: mask) ]
443+ pub fn check_mask ( ) {
444+ let a = kani:: any :: < usize > ( ) ;
445+ if let Some ( alignment) = Alignment :: new ( a) {
446+ assert_eq ! ( a & alignment. mask( ) , a) ;
386447 }
387448 }
388449}
0 commit comments