Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into align-harness
Browse files Browse the repository at this point in the history
  • Loading branch information
tautschnig committed Aug 8, 2024
2 parents 7fdbc77 + 0be79d6 commit a91dcad
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
26 changes: 26 additions & 0 deletions library/core/src/ascii/ascii_char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
//! suggestions from rustc if you get anything slightly wrong in here, and overall
//! helps with clarity as we're also referring to `char` intentionally in here.

use safety::{ensures, requires};
use crate::fmt::{self, Write};
use crate::mem::transmute;

#[cfg(kani)]
use crate::kani;

/// One of the 128 Unicode characters from U+0000 through U+007F,
/// often known as the [ASCII] subset.
///
Expand Down Expand Up @@ -449,6 +453,7 @@ impl AsciiChar {
/// or returns `None` if it's too large.
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
#[ensures(|result| (b <= 127) == (result.is_some() && result.unwrap() as u8 == b))]
pub const fn from_u8(b: u8) -> Option<Self> {
if b <= 127 {
// SAFETY: Just checked that `b` is in-range
Expand All @@ -466,6 +471,8 @@ impl AsciiChar {
/// `b` must be in `0..=127`, or else this is UB.
#[unstable(feature = "ascii_char", issue = "110998")]
#[inline]
#[requires(b <= 127)]
#[ensures(|result| *result as u8 == b)]
pub const unsafe fn from_u8_unchecked(b: u8) -> Self {
// SAFETY: Our safety precondition is that `b` is in-range.
unsafe { transmute(b) }
Expand Down Expand Up @@ -616,3 +623,22 @@ impl fmt::Debug for AsciiChar {
f.write_char('\'')
}
}

#[cfg(kani)]
#[unstable(feature="kani", issue="none")]
mod verify {
use super::*;
use AsciiChar;

#[kani::proof_for_contract(AsciiChar::from_u8)]
fn check_from_u8() {
let b: u8 = kani::any();
AsciiChar::from_u8(b);
}

#[kani::proof_for_contract(AsciiChar::from_u8_unchecked)]
fn check_from_u8_unchecked() {
let b: u8 = kani::any();
unsafe { AsciiChar::from_u8_unchecked(b) };
}
}
18 changes: 18 additions & 0 deletions library/core/src/char/convert.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
//! Character conversions.

use safety::{requires, ensures};
use crate::char::TryFromCharError;
use crate::error::Error;
use crate::fmt;
use crate::mem::transmute;
use crate::str::FromStr;
use crate::ub_checks::assert_unsafe_precondition;

#[cfg(kani)]
use crate::kani;

/// Converts a `u32` to a `char`. See [`char::from_u32`].
#[must_use]
#[inline]
Expand All @@ -21,6 +25,8 @@ pub(super) const fn from_u32(i: u32) -> Option<char> {
/// Converts a `u32` to a `char`, ignoring validity. See [`char::from_u32_unchecked`].
#[inline]
#[must_use]
#[requires(char_try_from_u32(i).is_ok())]
#[ensures(|result| *result as u32 == i)]
pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
// SAFETY: the caller must guarantee that `i` is a valid char value.
unsafe {
Expand Down Expand Up @@ -290,3 +296,15 @@ pub(super) const fn from_digit(num: u32, radix: u32) -> Option<char> {
None
}
}

#[cfg(kani)]
#[unstable(feature="kani", issue="none")]
mod verify {
use super::*;

#[kani::proof_for_contract(from_u32_unchecked)]
fn check_from_u32_unchecked() {
let i: u32 = kani::any();
unsafe { from_u32_unchecked(i) };
}
}
27 changes: 27 additions & 0 deletions library/core/src/char/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ use crate::str::from_utf8_unchecked_mut;
use crate::unicode::printable::is_printable;
use crate::unicode::{self, conversions};

#[cfg(kani)]
use crate::kani;

use super::*;

impl char {
Expand Down Expand Up @@ -1836,3 +1839,27 @@ pub fn encode_utf16_raw(mut code: u32, dst: &mut [u16]) -> &mut [u16] {
}
}
}

#[cfg(kani)]
#[unstable(feature="kani", issue="none")]
mod verify {
use super::*;
use safety::ensures;

#[ensures(|result| c.is_ascii() == (result.is_some() && (result.unwrap() as u8 as char == *c)))]
fn as_ascii_clone(c: &char) -> Option<ascii::Char> {
c.as_ascii()
}

#[kani::proof_for_contract(as_ascii_clone)]
fn check_as_ascii_ascii_char() {
let ascii: char = kani::any_where(|c : &char| c.is_ascii());
as_ascii_clone(&ascii);
}

#[kani::proof_for_contract(as_ascii_clone)]
fn check_as_ascii_non_ascii_char() {
let non_ascii: char = kani::any_where(|c: &char| !c.is_ascii());
as_ascii_clone(&non_ascii);
}
}

0 comments on commit a91dcad

Please sign in to comment.