Skip to content

Commit 29b2c87

Browse files
committed
Add safety preconditions to alloc/src/collections/binary_heap/mod.rs
This diff adds `#[requires(...)]` attributes to the unsafe functions, translating the "SAFETY:" comments into code contracts. These contracts specify the preconditions that must be met for the function to be safely called.
1 parent dc862c4 commit 29b2c87

File tree

1 file changed

+42
-0
lines changed
  • library/alloc/src/collections/binary_heap

1 file changed

+42
-0
lines changed

library/alloc/src/collections/binary_heap/mod.rs

+42
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@
143143
#![allow(missing_docs)]
144144
#![stable(feature = "rust1", since = "1.0.0")]
145145

146+
use safety::requires;
147+
#[cfg(kani)]
148+
use crate::kani;
149+
146150
use core::alloc::Allocator;
147151
use core::iter::{FusedIterator, InPlaceIterable, SourceIter, TrustedFused, TrustedLen};
148152
use core::mem::{self, swap, ManuallyDrop};
@@ -672,6 +676,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
672676
/// # Safety
673677
///
674678
/// The caller must guarantee that `pos < self.len()`.
679+
#[requires(pos < self.len())]
675680
unsafe fn sift_up(&mut self, start: usize, pos: usize) -> usize {
676681
// Take out the value at `pos` and create a hole.
677682
// SAFETY: The caller guarantees that pos < self.len()
@@ -701,6 +706,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
701706
/// # Safety
702707
///
703708
/// The caller must guarantee that `pos < end <= self.len()`.
709+
#[requires(pos < end && end <= self.len())]
704710
unsafe fn sift_down_range(&mut self, pos: usize, end: usize) {
705711
// SAFETY: The caller guarantees that pos < end <= self.len().
706712
let mut hole = unsafe { Hole::new(&mut self.data, pos) };
@@ -741,6 +747,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
741747
/// # Safety
742748
///
743749
/// The caller must guarantee that `pos < self.len()`.
750+
#[requires(pos < self.len())]
744751
unsafe fn sift_down(&mut self, pos: usize) {
745752
let len = self.len();
746753
// SAFETY: pos < len is guaranteed by the caller and
@@ -757,6 +764,7 @@ impl<T: Ord, A: Allocator> BinaryHeap<T, A> {
757764
/// # Safety
758765
///
759766
/// The caller must guarantee that `pos < self.len()`.
767+
#[requires(pos < self.len())]
760768
unsafe fn sift_down_to_bottom(&mut self, mut pos: usize) {
761769
let end = self.len();
762770
let start = pos;
@@ -1897,3 +1905,37 @@ 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+
1914+
// unsafe fn sift_up(&mut self, start: usize, pos: usize) -> usize
1915+
#[kani::proof_for_contract(impl<T::sift_up)]
1916+
pub fn check_sift_up() {
1917+
let obj : impl<T = kani::any();
1918+
let _ = obj.sift_up(kani::any());
1919+
}
1920+
1921+
// unsafe fn sift_down_range(&mut self, pos: usize, end: usize)
1922+
#[kani::proof_for_contract(impl<T::sift_down_range)]
1923+
pub fn check_sift_down_range() {
1924+
let obj : impl<T = kani::any();
1925+
let _ = obj.sift_down_range(kani::any());
1926+
}
1927+
1928+
// unsafe fn sift_down(&mut self, pos: usize)
1929+
#[kani::proof_for_contract(impl<T::sift_down)]
1930+
pub fn check_sift_down() {
1931+
let obj : impl<T = kani::any();
1932+
let _ = obj.sift_down(kani::any());
1933+
}
1934+
1935+
// unsafe fn sift_down_to_bottom(&mut self, mut pos: usize)
1936+
#[kani::proof_for_contract(impl<T::sift_down_to_bottom)]
1937+
pub fn check_sift_down_to_bottom() {
1938+
let obj : impl<T = kani::any();
1939+
let _ = obj.sift_down_to_bottom(kani::any());
1940+
}
1941+
}

0 commit comments

Comments
 (0)