@@ -33,6 +33,11 @@ use crate::vec::Vec;
3333#[ cfg( test) ]
3434mod tests;
3535
36+ use safety:: { requires, ensures} ;
37+
38+ #[ cfg( kani) ]
39+ use core:: kani;
40+
3641#[ unstable( feature = "array_chunks" , issue = "74985" ) ]
3742pub use core:: slice:: ArrayChunks ;
3843#[ unstable( feature = "array_chunks" , issue = "74985" ) ]
@@ -538,12 +543,16 @@ impl<T> [T] {
538543 // Using `Vec` to access `set_len()`.
539544 let capacity = self . len ( ) . checked_mul ( n) . expect ( "capacity overflow" ) ;
540545 let mut buf = Vec :: with_capacity ( capacity) ;
546+ let old_len = self . len ( ) ;
541547
542548 // `2^expn` repetition is done by doubling `buf` `expn`-times.
543549 buf. extend ( self ) ;
544550 {
545551 let mut m = n >> 1 ;
546552 // If `m > 0`, there are remaining bits up to the leftmost '1'.
553+ #[ cfg_attr( kani, kani:: loop_invariant( m <= n >> 1
554+ && ( m == 0 || ( old_len * ( n/( m << 2 ) ) <= buf. len( ) && buf. len( ) <= old_len * ( ( n/( m << 1 ) ) ) )
555+ && ( m != 0 || ( old_len * ( ( n+1 ) /2 ) <= buf. len( ) && buf. len( ) <= old_len * n) ) ) ) ) ]
547556 while m > 0 {
548557 // `buf.extend(buf)`:
549558 unsafe {
@@ -893,3 +902,41 @@ impl<T> sort::stable::BufGuard<T> for Vec<T> {
893902 self . spare_capacity_mut ( )
894903 }
895904}
905+
906+ #[ cfg( kani) ]
907+ #[ unstable( feature = "kani" , issue = "none" ) ]
908+ mod verify {
909+ use super :: * ;
910+
911+ pub fn any_slice_of_array < T , const LENGTH : usize > ( arr : & [ T ; LENGTH ] ) -> & [ T ] {
912+ let ( from, to) = any_range :: < LENGTH > ( ) ;
913+ & arr[ from..to]
914+ }
915+
916+ /// A mutable version of the previous function
917+ pub fn any_slice_of_array_mut < T , const LENGTH : usize > ( arr : & mut [ T ; LENGTH ] ) -> & mut [ T ] {
918+ let ( from, to) = any_range :: < LENGTH > ( ) ;
919+ & mut arr[ from..to]
920+ }
921+
922+ fn any_range < const LENGTH : usize > ( ) -> ( usize , usize ) {
923+ let from: usize = kani:: any ( ) ;
924+ let to: usize = kani:: any ( ) ;
925+ kani:: assume ( to <= LENGTH ) ;
926+ kani:: assume ( from <= to) ;
927+ ( from, to)
928+ }
929+
930+ #[ kani:: proof]
931+ pub fn check_repeat ( ) {
932+ let _ = Box :: new ( 0 ) ;
933+ const ARR_SIZE : usize = 1000 ;
934+ const REPEAT_TIMES : usize = 100 ;
935+ let n = kani:: any_where ( |i| * i < REPEAT_TIMES ) ;
936+ let mut x: [ u8 ; ARR_SIZE ] = kani:: any ( ) ;
937+ let xs = any_slice_of_array_mut ( & mut x) ;
938+ unsafe {
939+ xs. repeat ( n) ;
940+ }
941+ }
942+ }
0 commit comments