Skip to content

Commit

Permalink
Unify kani library and kani core logic (#3333)
Browse files Browse the repository at this point in the history
1. Unifies `Kani library` and `kani_core` for `Arbitrary`, `mem` and
`intrinsics` along with the `internal` module.
2. Adjusts some regression expected files to reflect the new underlying
source of Arbitrary

Related to ##3257

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
  • Loading branch information
jaisnan authored Aug 6, 2024
1 parent 6eb7ddd commit 2a0e9bd
Show file tree
Hide file tree
Showing 14 changed files with 71 additions and 1,082 deletions.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
name = "kani"
version = "0.53.0"
dependencies = [
"kani_core",
"kani_macros",
]

Expand Down
2 changes: 2 additions & 0 deletions library/kani/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ publish = false

[dependencies]
kani_macros = { path = "../kani_macros" }
kani_core = { path = "../kani_core" }

[features]
concrete_playback = []
no_core=["kani_macros/no_core"]
146 changes: 1 addition & 145 deletions library/kani/src/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,151 +4,7 @@
//! This module introduces the `Arbitrary` trait as well as implementation for
//! primitive types and other std containers.

use std::{
marker::{PhantomData, PhantomPinned},
num::*,
};

/// This trait should be used to generate symbolic variables that represent any valid value of
/// its type.
pub trait Arbitrary
where
Self: Sized,
{
fn any() -> Self;
fn any_array<const MAX_ARRAY_LENGTH: usize>() -> [Self; MAX_ARRAY_LENGTH] {
[(); MAX_ARRAY_LENGTH].map(|_| Self::any())
}
}

/// The given type can be represented by an unconstrained symbolic value of size_of::<T>.
macro_rules! trivial_arbitrary {
( $type: ty ) => {
impl Arbitrary for $type {
#[inline(always)]
fn any() -> Self {
// This size_of call does not use generic_const_exprs feature. It's inside a macro, and Self isn't generic.
unsafe { crate::any_raw_internal::<Self>() }
}
fn any_array<const MAX_ARRAY_LENGTH: usize>() -> [Self; MAX_ARRAY_LENGTH] {
unsafe { crate::any_raw_array::<Self, MAX_ARRAY_LENGTH>() }
}
}
};
}

trivial_arbitrary!(u8);
trivial_arbitrary!(u16);
trivial_arbitrary!(u32);
trivial_arbitrary!(u64);
trivial_arbitrary!(u128);
trivial_arbitrary!(usize);

trivial_arbitrary!(i8);
trivial_arbitrary!(i16);
trivial_arbitrary!(i32);
trivial_arbitrary!(i64);
trivial_arbitrary!(i128);
trivial_arbitrary!(isize);

// We do not constrain floating points values per type spec. Users must add assumptions to their
// verification code if they want to eliminate NaN, infinite, or subnormal.
trivial_arbitrary!(f32);
trivial_arbitrary!(f64);

// Similarly, we do not constraint values for non-standard floating types.
trivial_arbitrary!(f16);
trivial_arbitrary!(f128);

trivial_arbitrary!(());

impl Arbitrary for bool {
#[inline(always)]
fn any() -> Self {
let byte = u8::any();
crate::assume(byte < 2);
byte == 1
}
}

/// Validate that a char is not outside the ranges [0x0, 0xD7FF] and [0xE000, 0x10FFFF]
/// Ref: <https://doc.rust-lang.org/stable/nomicon/what-unsafe-does.html>
impl Arbitrary for char {
#[inline(always)]
fn any() -> Self {
// Generate an arbitrary u32 and constrain it to make it a valid representation of char.
let val = u32::any();
crate::assume(val <= 0xD7FF || (0xE000..=0x10FFFF).contains(&val));
unsafe { char::from_u32_unchecked(val) }
}
}

macro_rules! nonzero_arbitrary {
( $type: ty, $base: ty ) => {
impl Arbitrary for $type {
#[inline(always)]
fn any() -> Self {
let val = <$base>::any();
crate::assume(val != 0);
unsafe { <$type>::new_unchecked(val) }
}
}
};
}

nonzero_arbitrary!(NonZeroU8, u8);
nonzero_arbitrary!(NonZeroU16, u16);
nonzero_arbitrary!(NonZeroU32, u32);
nonzero_arbitrary!(NonZeroU64, u64);
nonzero_arbitrary!(NonZeroU128, u128);
nonzero_arbitrary!(NonZeroUsize, usize);

nonzero_arbitrary!(NonZeroI8, i8);
nonzero_arbitrary!(NonZeroI16, i16);
nonzero_arbitrary!(NonZeroI32, i32);
nonzero_arbitrary!(NonZeroI64, i64);
nonzero_arbitrary!(NonZeroI128, i128);
nonzero_arbitrary!(NonZeroIsize, isize);

impl<T, const N: usize> Arbitrary for [T; N]
where
T: Arbitrary,
{
fn any() -> Self {
T::any_array()
}
}

impl<T> Arbitrary for Option<T>
where
T: Arbitrary,
{
fn any() -> Self {
if bool::any() { Some(T::any()) } else { None }
}
}

impl<T, E> Arbitrary for Result<T, E>
where
T: Arbitrary,
E: Arbitrary,
{
fn any() -> Self {
if bool::any() { Ok(T::any()) } else { Err(E::any()) }
}
}

impl<T: ?Sized> Arbitrary for std::marker::PhantomData<T> {
fn any() -> Self {
PhantomData
}
}

impl Arbitrary for std::marker::PhantomPinned {
fn any() -> Self {
PhantomPinned
}
}
use crate::Arbitrary;

impl<T> Arbitrary for std::boxed::Box<T>
where
Expand Down
160 changes: 0 additions & 160 deletions library/kani/src/internal.rs

This file was deleted.

Loading

0 comments on commit 2a0e9bd

Please sign in to comment.