Skip to content

Commit a0fca1c

Browse files
vonakaFedor Ryabinintautschnig
authored
A bunch of LLM-generated contracts (#451)
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses. --------- Co-authored-by: Fedor Ryabinin <[email protected]> Co-authored-by: Michael Tautschnig <[email protected]>
1 parent cd5e611 commit a0fca1c

File tree

4 files changed

+63
-0
lines changed

4 files changed

+63
-0
lines changed

library/core/src/hint.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
//!
55
//! Hints may be compile time or runtime.
66
7+
use safety::requires;
8+
9+
#[cfg(kani)]
10+
use crate::kani;
711
use crate::mem::MaybeUninit;
812
use crate::{intrinsics, ub_checks};
913

@@ -99,6 +103,7 @@ use crate::{intrinsics, ub_checks};
99103
#[stable(feature = "unreachable", since = "1.27.0")]
100104
#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
101105
#[track_caller]
106+
#[requires(false)]
102107
pub const unsafe fn unreachable_unchecked() -> ! {
103108
ub_checks::assert_unsafe_precondition!(
104109
check_language_ub,
@@ -198,6 +203,7 @@ pub const unsafe fn unreachable_unchecked() -> ! {
198203
#[doc(alias = "assume")]
199204
#[stable(feature = "hint_assert_unchecked", since = "1.81.0")]
200205
#[rustc_const_stable(feature = "hint_assert_unchecked", since = "1.81.0")]
206+
#[requires(cond)]
201207
pub const unsafe fn assert_unchecked(cond: bool) {
202208
// SAFETY: The caller promised `cond` is true.
203209
unsafe {

library/core/src/iter/adapters/step_by.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use crate::intrinsics;
22
use crate::iter::{TrustedLen, TrustedRandomAccess, from_fn};
3+
#[cfg(kani)]
4+
use crate::kani;
35
use crate::num::NonZero;
46
use crate::ops::{Range, Try};
7+
use crate::ub_checks::Invariant;
58

69
/// An iterator for stepping iterators by a custom amount.
710
///
@@ -29,6 +32,13 @@ pub struct StepBy<I> {
2932
first_take: bool,
3033
}
3134

35+
#[unstable(feature = "ub_checks", issue = "none")]
36+
impl<I> Invariant for StepBy<I> {
37+
fn is_safe(&self) -> bool {
38+
self.step_minus_one < usize::MAX
39+
}
40+
}
41+
3242
impl<I> StepBy<I> {
3343
#[inline]
3444
pub(in crate::iter) fn new(iter: I, step: usize) -> StepBy<I> {

library/core/src/ops/index_range.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
use safety::requires;
2+
13
use crate::iter::{FusedIterator, TrustedLen};
4+
#[cfg(kani)]
5+
use crate::kani;
26
use crate::num::NonZero;
37
use crate::ops::{NeverShortCircuit, Try};
48
use crate::ub_checks;
@@ -20,6 +24,7 @@ impl IndexRange {
2024
/// - `start <= end`
2125
#[inline]
2226
#[track_caller]
27+
#[requires(start <= end)]
2328
pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
2429
ub_checks::assert_unsafe_precondition!(
2530
check_library_ub,
@@ -54,6 +59,8 @@ impl IndexRange {
5459
/// # Safety
5560
/// - Can only be called when `start < end`, aka when `len > 0`.
5661
#[inline]
62+
#[requires(self.start < self.end)]
63+
#[cfg_attr(kani, kani::modifies(self))]
5764
unsafe fn next_unchecked(&mut self) -> usize {
5865
debug_assert!(self.start < self.end);
5966

@@ -66,6 +73,8 @@ impl IndexRange {
6673
/// # Safety
6774
/// - Can only be called when `start < end`, aka when `len > 0`.
6875
#[inline]
76+
#[requires(self.start < self.end)]
77+
#[cfg_attr(kani, kani::modifies(self))]
6978
unsafe fn next_back_unchecked(&mut self) -> usize {
7079
debug_assert!(self.start < self.end);
7180

@@ -225,3 +234,34 @@ impl ExactSizeIterator for IndexRange {
225234
unsafe impl TrustedLen for IndexRange {}
226235

227236
impl FusedIterator for IndexRange {}
237+
#[cfg(kani)]
238+
mod verify {
239+
use super::*;
240+
#[kani::proof_for_contract(IndexRange::new_unchecked)]
241+
fn proof_for_index_range_new_unchecked() {
242+
let start = kani::any::<usize>();
243+
let end = kani::any::<usize>();
244+
245+
unsafe { IndexRange::new_unchecked(start, end) };
246+
}
247+
248+
#[kani::proof_for_contract(IndexRange::next_unchecked)]
249+
fn proof_for_index_range_next_unchecked() {
250+
let start = kani::any::<usize>();
251+
let end = kani::any::<usize>();
252+
253+
let mut range = unsafe { IndexRange::new_unchecked(start, end) };
254+
255+
unsafe { range.next_unchecked() };
256+
}
257+
258+
#[kani::proof_for_contract(IndexRange::next_back_unchecked)]
259+
fn proof_for_index_range_next_back_unchecked() {
260+
let start = kani::any::<usize>();
261+
let end = kani::any::<usize>();
262+
263+
let mut range = unsafe { IndexRange::new_unchecked(start, end) };
264+
265+
unsafe { range.next_back_unchecked() };
266+
}
267+
}

library/std/src/sync/mpmc/context.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
//! Thread-local channel context.
22
3+
#[cfg(kani)]
4+
#[unstable(feature = "kani", issue = "none")]
5+
use core::kani;
6+
7+
use safety::requires;
8+
39
use super::select::Selected;
410
use super::waker::current_thread_id;
511
use crate::cell::Cell;
@@ -116,6 +122,7 @@ impl Context {
116122
/// # Safety
117123
/// This may only be called from the thread this `Context` belongs to.
118124
#[inline]
125+
#[requires(self.thread_id() == current_thread_id())]
119126
pub unsafe fn wait_until(&self, deadline: Option<Instant>) -> Selected {
120127
loop {
121128
// Check whether an operation has been selected.

0 commit comments

Comments
 (0)