Skip to content

Commit 60bf5c2

Browse files
committed
Add specs for digit_unchecked + comments
1 parent 56b7ef9 commit 60bf5c2

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

library/core/src/ascii/ascii_char.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,7 @@ impl AsciiChar {
479479
/// `b` must be in `0..=127`, or else this is UB.
480480
#[unstable(feature = "ascii_char", issue = "110998")]
481481
#[inline]
482+
#[cfg_attr(flux, flux::spec(fn(b: u8{b <= 127}) -> Self))]
482483
#[requires(b <= 127)]
483484
#[ensures(|result| *result as u8 == b)]
484485
pub const unsafe fn from_u8_unchecked(b: u8) -> Self {
@@ -516,6 +517,7 @@ impl AsciiChar {
516517
/// when writing code using this method, since the implementation doesn't
517518
/// need something really specific, not to make those other arguments do
518519
/// something useful. It might be tightened before stabilization.)
520+
#[cfg_attr(flux, flux::spec(fn(d: u8{d < 10}) -> Self))]
519521
#[unstable(feature = "ascii_char", issue = "110998")]
520522
#[inline]
521523
#[track_caller]

library/core/src/num/uint_macros.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ macro_rules! uint_impl {
581581
without modifying the original"]
582582
#[inline(always)]
583583
#[track_caller]
584+
#[cfg_attr(flux, flux::spec(fn(self: Self, rhs: Self{self + rhs <= $MaxV}) -> Self[self + rhs]))]
584585
#[requires(!self.overflowing_add(rhs).1)]
585586
pub const unsafe fn unchecked_add(self, rhs: Self) -> Self {
586587
assert_unsafe_precondition!(

library/core/src/pat.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@ macro_rules! pattern_type {
1313
};
1414
}
1515

16+
// The Flux spec for the `trait RangePattern` below uses
17+
// [associated refinements](https://flux-rs.github.io/flux/tutorial/08-traits.html)
18+
// The `sub_one` method may only be safe for certain values,
19+
// e.g. when the value is not the "minimum of the type" as in the
20+
// case of the `char` implementation below. To specify this precondition generically
21+
// 1. at the trait level, we introduce the predicate `sub_ok`
22+
// which characterizes the "valid" values at which `sub_one`
23+
// can be safely called, and by default, specify this predicate
24+
// is "true";
25+
// 2. at the impl level, we can provide a type-specific implementation
26+
// of `sub_ok` that permits the verification of the impl for that type.
27+
1628
/// A trait implemented for integer types and `char`.
1729
/// Useful in the future for generic pattern types, but
1830
/// used right now to simplify ast lowering of pattern type ranges.
@@ -63,13 +75,16 @@ impl_range_pat! {
6375
u8, u16, u32, u64, u128, usize,
6476
}
6577

78+
// The "associated refinement" `sub_ok` is defined as `non-zero` for `char`, to let Flux
79+
// verify that the `self as u32 -1` in the impl does not underflow.
6680
#[cfg_attr(flux, flux::assoc(fn sub_ok(self: char) -> bool { 0 < char_to_int(self)}))]
6781
#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
6882
impl const RangePattern for char {
6983
const MIN: Self = char::MIN;
7084

7185
const MAX: Self = char::MAX;
7286

87+
7388
#[cfg_attr(flux, flux::spec(fn (self: char{<char as RangePattern>::sub_ok(self)}) -> char))]
7489
fn sub_one(self) -> Self {
7590
match char::from_u32(self as u32 - 1) {

0 commit comments

Comments
 (0)