@@ -13,6 +13,18 @@ macro_rules! pattern_type {
13
13
} ;
14
14
}
15
15
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
+
16
28
/// A trait implemented for integer types and `char`.
17
29
/// Useful in the future for generic pattern types, but
18
30
/// used right now to simplify ast lowering of pattern type ranges.
@@ -63,13 +75,16 @@ impl_range_pat! {
63
75
u8 , u16 , u32 , u64 , u128 , usize ,
64
76
}
65
77
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.
66
80
#[ cfg_attr( flux, flux:: assoc( fn sub_ok( self : char ) -> bool { 0 < char_to_int( self ) } ) ) ]
67
81
#[ rustc_const_unstable( feature = "pattern_type_range_trait" , issue = "123646" ) ]
68
82
impl const RangePattern for char {
69
83
const MIN : Self = char:: MIN ;
70
84
71
85
const MAX : Self = char:: MAX ;
72
86
87
+
73
88
#[ cfg_attr( flux, flux:: spec( fn ( self : char { <char as RangePattern >:: sub_ok( self ) } ) -> char ) ) ]
74
89
fn sub_one ( self ) -> Self {
75
90
match char:: from_u32 ( self as u32 - 1 ) {
0 commit comments