@@ -155,6 +155,12 @@ use crate::collections::TryReserveError;
155155use crate :: slice;
156156use crate :: vec:: { self , AsVecIntoIter , Vec } ;
157157
158+ use safety:: { ensures, requires} ;
159+
160+ #[ cfg( kani) ]
161+ #[ unstable( feature="kani" , issue="none" ) ]
162+ use core:: kani;
163+
158164#[ cfg( test) ]
159165mod tests;
160166
@@ -672,11 +678,13 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
672678 /// # Safety
673679 ///
674680 /// The caller must guarantee that `pos < self.len()`.
681+ #[ requires( pos < self . len( ) && start <= pos) ]
675682 unsafe fn sift_up ( & mut self , start : usize , pos : usize ) -> usize {
676683 // Take out the value at `pos` and create a hole.
677684 // SAFETY: The caller guarantees that pos < self.len()
678685 let mut hole = unsafe { Hole :: new ( & mut self . data , pos) } ;
679686
687+ #[ cfg_attr( kani, kani:: loop_invariant( hole. pos( ) <= pos) ) ]
680688 while hole. pos ( ) > start {
681689 let parent = ( hole. pos ( ) - 1 ) / 2 ;
682690
@@ -1897,3 +1905,61 @@ impl<'a, T: 'a + Ord + Copy, A: Allocator> Extend<&'a T> for BinaryHeap<T, A> {
18971905 self . reserve ( additional) ;
18981906 }
18991907}
1908+
1909+ #[ cfg( kani) ]
1910+ #[ unstable( feature = "kani" , issue = "none" ) ]
1911+ mod verify {
1912+ use super :: * ;
1913+ use crate :: boxed:: Box ;
1914+
1915+ /// Generates an arbitrary vector whose length is at most MAX_LENGTH.
1916+ pub fn any_vec < T , const MAX_LENGTH : usize > ( ) -> Vec < T >
1917+ where
1918+ T : kani:: Arbitrary ,
1919+ {
1920+ let real_length: usize = kani:: any_where ( |sz| * sz <= MAX_LENGTH ) ;
1921+ match real_length {
1922+ 0 => vec ! [ ] ,
1923+ exact if exact == MAX_LENGTH => exact_vec :: < T , MAX_LENGTH > ( ) ,
1924+ _ => {
1925+ let mut any_vec = exact_vec :: < T , MAX_LENGTH > ( ) ;
1926+ any_vec. truncate ( real_length) ;
1927+ any_vec. shrink_to_fit ( ) ;
1928+ assert ! ( any_vec. capacity( ) == any_vec. len( ) ) ;
1929+ any_vec
1930+ }
1931+ }
1932+ }
1933+
1934+ /// Generates an arbitrary vector that is exactly EXACT_LENGTH long.
1935+ pub fn exact_vec < T , const EXACT_LENGTH : usize > ( ) -> Vec < T >
1936+ where
1937+ T : kani:: Arbitrary ,
1938+ {
1939+ let boxed_array: Box < [ T ; EXACT_LENGTH ] > = Box :: new ( kani:: any ( ) ) ;
1940+ <[ T ] >:: into_vec ( boxed_array)
1941+ }
1942+
1943+ fn any_binary_heap < T : kani:: Arbitrary , const MAX_SIZE : usize > ( ) -> BinaryHeap < T > {
1944+ let data: Vec < T > = any_vec :: < T , MAX_SIZE > ( ) ;
1945+ BinaryHeap { data }
1946+ }
1947+
1948+ #[ kani:: proof]
1949+ pub fn check_any_binary_heap ( ) {
1950+ let h: BinaryHeap < u8 > = any_binary_heap :: < u8 , 8 > ( ) ;
1951+ assert ! ( h. len( ) <= 8 ) ;
1952+ }
1953+
1954+ #[ kani:: proof]
1955+ pub fn check_sift_up ( ) {
1956+ let _ = Box :: new ( 0 ) ;
1957+ const MAX_SIZE : usize = 1000 ;
1958+ let mut h: BinaryHeap < u8 > = any_binary_heap :: < u8 , MAX_SIZE > ( ) ;
1959+ let pos: usize = kani:: any_where ( |x| * x < h. len ( ) ) ;
1960+ let start: usize = kani:: any_where ( |x| * x <= pos) ;
1961+ unsafe {
1962+ h. sift_up ( start, pos) ;
1963+ }
1964+ }
1965+ }
0 commit comments