Skip to content

A bunch of LLM-generated contracts #451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions library/core/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
//!
//! Hints may be compile time or runtime.
use safety::requires;

#[cfg(kani)]
use crate::kani;
use crate::mem::MaybeUninit;
use crate::{intrinsics, ub_checks};

Expand Down Expand Up @@ -99,6 +103,7 @@ use crate::{intrinsics, ub_checks};
#[stable(feature = "unreachable", since = "1.27.0")]
#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
#[track_caller]
#[requires(false)]
pub const unsafe fn unreachable_unchecked() -> ! {
ub_checks::assert_unsafe_precondition!(
check_language_ub,
Expand Down Expand Up @@ -198,6 +203,7 @@ pub const unsafe fn unreachable_unchecked() -> ! {
#[doc(alias = "assume")]
#[stable(feature = "hint_assert_unchecked", since = "1.81.0")]
#[rustc_const_stable(feature = "hint_assert_unchecked", since = "1.81.0")]
#[requires(cond)]
pub const unsafe fn assert_unchecked(cond: bool) {
// SAFETY: The caller promised `cond` is true.
unsafe {
Expand Down
10 changes: 10 additions & 0 deletions library/core/src/iter/adapters/step_by.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::intrinsics;
use crate::iter::{TrustedLen, TrustedRandomAccess, from_fn};
#[cfg(kani)]
use crate::kani;
use crate::num::NonZero;
use crate::ops::{Range, Try};
use crate::ub_checks::Invariant;

/// An iterator for stepping iterators by a custom amount.
///
Expand Down Expand Up @@ -29,6 +32,13 @@ pub struct StepBy<I> {
first_take: bool,
}

#[unstable(feature = "ub_checks", issue = "none")]
impl<I> Invariant for StepBy<I> {
fn is_safe(&self) -> bool {
self.step_minus_one < usize::MAX
}
}

impl<I> StepBy<I> {
#[inline]
pub(in crate::iter) fn new(iter: I, step: usize) -> StepBy<I> {
Expand Down
40 changes: 40 additions & 0 deletions library/core/src/ops/index_range.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use safety::requires;

use crate::iter::{FusedIterator, TrustedLen};
#[cfg(kani)]
use crate::kani;
use crate::num::NonZero;
use crate::ops::{NeverShortCircuit, Try};
use crate::ub_checks;
Expand All @@ -20,6 +24,7 @@ impl IndexRange {
/// - `start <= end`
#[inline]
#[track_caller]
#[requires(start <= end)]
pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self {
ub_checks::assert_unsafe_precondition!(
check_library_ub,
Expand Down Expand Up @@ -54,6 +59,8 @@ impl IndexRange {
/// # Safety
/// - Can only be called when `start < end`, aka when `len > 0`.
#[inline]
#[requires(self.start < self.end)]
#[cfg_attr(kani, kani::modifies(self))]
unsafe fn next_unchecked(&mut self) -> usize {
debug_assert!(self.start < self.end);

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

Expand Down Expand Up @@ -225,3 +234,34 @@ impl ExactSizeIterator for IndexRange {
unsafe impl TrustedLen for IndexRange {}

impl FusedIterator for IndexRange {}
#[cfg(kani)]
mod verify {
use super::*;
#[kani::proof_for_contract(IndexRange::new_unchecked)]
fn proof_for_index_range_new_unchecked() {
let start = kani::any::<usize>();
let end = kani::any::<usize>();

unsafe { IndexRange::new_unchecked(start, end) };
}

#[kani::proof_for_contract(IndexRange::next_unchecked)]
fn proof_for_index_range_next_unchecked() {
let start = kani::any::<usize>();
let end = kani::any::<usize>();

let mut range = unsafe { IndexRange::new_unchecked(start, end) };

unsafe { range.next_unchecked() };
}

#[kani::proof_for_contract(IndexRange::next_back_unchecked)]
fn proof_for_index_range_next_back_unchecked() {
let start = kani::any::<usize>();
let end = kani::any::<usize>();

let mut range = unsafe { IndexRange::new_unchecked(start, end) };

unsafe { range.next_back_unchecked() };
}
}
7 changes: 7 additions & 0 deletions library/std/src/sync/mpmc/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
//! Thread-local channel context.
#[cfg(kani)]
#[unstable(feature = "kani", issue = "none")]
use core::kani;

use safety::requires;

use super::select::Selected;
use super::waker::current_thread_id;
use crate::cell::Cell;
Expand Down Expand Up @@ -116,6 +122,7 @@ impl Context {
/// # Safety
/// This may only be called from the thread this `Context` belongs to.
#[inline]
#[requires(self.thread_id() == current_thread_id())]
pub unsafe fn wait_until(&self, deadline: Option<Instant>) -> Selected {
loop {
// Check whether an operation has been selected.
Expand Down
Loading