@@ -123,6 +123,11 @@ pub enum SimpleLine {
123123 location : SourceLocation ,
124124 } ,
125125 DebugAssert ( BooleanExpr < SimpleExpr > , SourceLocation ) ,
126+ /// Range check: assert val <= bound
127+ RangeCheck {
128+ val : SimpleExpr ,
129+ bound : SimpleExpr ,
130+ } ,
126131}
127132
128133impl SimpleLine {
@@ -157,7 +162,8 @@ impl SimpleLine {
157162 | Self :: HintMAlloc { .. }
158163 | Self :: ConstMalloc { .. }
159164 | Self :: LocationReport { .. }
160- | Self :: DebugAssert ( ..) => vec ! [ ] ,
165+ | Self :: DebugAssert ( ..)
166+ | Self :: RangeCheck { .. } => vec ! [ ] ,
161167 }
162168 }
163169
@@ -182,7 +188,8 @@ impl SimpleLine {
182188 | Self :: HintMAlloc { .. }
183189 | Self :: ConstMalloc { .. }
184190 | Self :: LocationReport { .. }
185- | Self :: DebugAssert ( ..) => vec ! [ ] ,
191+ | Self :: DebugAssert ( ..)
192+ | Self :: RangeCheck { .. } => vec ! [ ] ,
186193 }
187194 }
188195}
@@ -2257,6 +2264,49 @@ fn simplify_lines(
22572264 } ;
22582265 res. push ( SimpleLine :: equality ( var, other) ) ;
22592266 }
2267+ Boolean :: LessThan => {
2268+ // assert left < right is equivalent to assert left <= right - 1
2269+ let bound_minus_one = state. counters . aux_var ( ) ;
2270+ res. push ( SimpleLine :: Assignment {
2271+ var : bound_minus_one. clone ( ) . into ( ) ,
2272+ operation : MathOperation :: Sub ,
2273+ arg0 : right,
2274+ arg1 : SimpleExpr :: one ( ) ,
2275+ } ) ;
2276+
2277+ // We add a debug assert for sanity
2278+ res. push ( SimpleLine :: DebugAssert (
2279+ BooleanExpr {
2280+ kind : Boolean :: LessOrEqual ,
2281+ left : left. clone ( ) ,
2282+ right : bound_minus_one. clone ( ) . into ( ) ,
2283+ } ,
2284+ * location,
2285+ ) ) ;
2286+
2287+ res. push ( SimpleLine :: RangeCheck {
2288+ val : left,
2289+ bound : bound_minus_one. into ( ) ,
2290+ } ) ;
2291+ }
2292+ Boolean :: LessOrEqual => {
2293+ // Range check: assert left <= right
2294+
2295+ // we add a debug assert for sanity
2296+ res. push ( SimpleLine :: DebugAssert (
2297+ BooleanExpr {
2298+ kind : Boolean :: LessOrEqual ,
2299+ left : left. clone ( ) ,
2300+ right : right. clone ( ) ,
2301+ } ,
2302+ * location,
2303+ ) ) ;
2304+
2305+ res. push ( SimpleLine :: RangeCheck {
2306+ val : left,
2307+ bound : right,
2308+ } ) ;
2309+ }
22602310 }
22612311 }
22622312 }
@@ -2273,6 +2323,7 @@ fn simplify_lines(
22732323 let ( left, right, then_branch, else_branch) = match condition. kind {
22742324 Boolean :: Equal => ( & condition. left , & condition. right , else_branch, then_branch) , // switched
22752325 Boolean :: Different => ( & condition. left , & condition. right , then_branch, else_branch) ,
2326+ Boolean :: LessThan | Boolean :: LessOrEqual => unreachable ! ( ) ,
22762327 } ;
22772328
22782329 let left_simplified = simplify_expr ( ctx, state, const_malloc, left, & mut res) ?;
@@ -3564,6 +3615,9 @@ impl SimpleLine {
35643615 Self :: DebugAssert ( bool, _) => {
35653616 format ! ( "debug_assert({bool})" )
35663617 }
3618+ Self :: RangeCheck { val, bound } => {
3619+ format ! ( "range_check({val} <= {bound})" )
3620+ }
35673621 } ;
35683622 format ! ( "{spaces}{line_str}" )
35693623 }
0 commit comments