@@ -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" ) ]
6882impl 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