@@ -149,3 +149,53 @@ mod tests {
149149 }
150150 }
151151}
152+
153+ #[ cfg( kani) ]
154+ mod proofs {
155+ use super :: * ;
156+
157+ #[ kani:: proof]
158+ fn prove_round_down_to_next_multiple_of_alignment ( ) {
159+ fn model_impl ( n : usize , align : NonZeroUsize ) -> usize {
160+ assert ! ( align. get( ) . is_power_of_two( ) ) ;
161+ let mul = n / align. get ( ) ;
162+ mul * align. get ( )
163+ }
164+
165+ let align: NonZeroUsize = kani:: any ( ) ;
166+ kani:: assume ( align. get ( ) . is_power_of_two ( ) ) ;
167+ let n: usize = kani:: any ( ) ;
168+
169+ let expected = model_impl ( n, align) ;
170+ let actual = _round_down_to_next_multiple_of_alignment ( n, align) ;
171+ assert_eq ! ( expected, actual, "round_down_to_next_multiple_of_alignment({n}, {align})" ) ;
172+ }
173+
174+ // Restricted to nightly since we use the unstable `usize::next_multiple_of`
175+ // in our model implementation.
176+ #[ cfg( __INTERNAL_USE_ONLY_NIGHLTY_FEATURES_IN_TESTS) ]
177+ #[ kani:: proof]
178+ fn prove_padding_needed_for ( ) {
179+ fn model_impl ( len : usize , align : NonZeroUsize ) -> usize {
180+ let padded = len. next_multiple_of ( align. get ( ) ) ;
181+ let padding = padded - len;
182+ padding
183+ }
184+
185+ let align: NonZeroUsize = kani:: any ( ) ;
186+ kani:: assume ( align. get ( ) . is_power_of_two ( ) ) ;
187+ let len: usize = kani:: any ( ) ;
188+ // Constrain `len` to valid Rust lengths, since our model implementation
189+ // isn't robust to overflow.
190+ kani:: assume ( len <= isize:: MAX as usize ) ;
191+ kani:: assume ( align. get ( ) < 1 << 29 ) ;
192+
193+ let expected = model_impl ( len, align) ;
194+ let actual = core_layout:: _padding_needed_for ( len, align) ;
195+ assert_eq ! ( expected, actual, "padding_needed_for({len}, {align})" ) ;
196+
197+ let padded_len = actual + len;
198+ assert_eq ! ( padded_len % align, 0 ) ;
199+ assert ! ( padded_len / align >= len / align) ;
200+ }
201+ }
0 commit comments