@@ -68,6 +68,11 @@ impl [u8] {
68
68
let mut a = self ;
69
69
let mut b = other;
70
70
71
+ #[ safety:: loop_invariant(
72
+ a. len( ) <= self . len( ) && b. len( ) <= other. len( ) &&
73
+ ( a. len( ) == 0 || self . as_ptr( ) . wrapping_add( self . len( ) -a. len( ) ) == a. as_ptr( ) ) &&
74
+ ( b. len( ) == 0 || other. as_ptr( ) . wrapping_add( other. len( ) -b. len( ) ) == b. as_ptr( ) )
75
+ ) ]
71
76
while let ( [ first_a, rest_a @ ..] , [ first_b, rest_b @ ..] ) = ( a, b) {
72
77
if first_a. eq_ignore_ascii_case ( & first_b) {
73
78
a = rest_a;
@@ -160,6 +165,10 @@ impl [u8] {
160
165
let mut bytes = self ;
161
166
// Note: A pattern matching based approach (instead of indexing) allows
162
167
// making the function const.
168
+ #[ safety:: loop_invariant(
169
+ bytes. len( ) <= self . len( ) &&
170
+ ( bytes. len( ) == 0 || self . as_ptr( ) . wrapping_add( self . len( ) -bytes. len( ) ) == bytes. as_ptr( ) )
171
+ ) ]
163
172
while let [ first, rest @ ..] = bytes {
164
173
if first. is_ascii_whitespace ( ) {
165
174
bytes = rest;
@@ -189,6 +198,10 @@ impl [u8] {
189
198
let mut bytes = self ;
190
199
// Note: A pattern matching based approach (instead of indexing) allows
191
200
// making the function const.
201
+ #[ safety:: loop_invariant(
202
+ bytes. len( ) <= self . len( ) &&
203
+ ( bytes. len( ) == 0 || self . as_ptr( ) == bytes. as_ptr( ) )
204
+ ) ]
192
205
while let [ rest @ .., last] = bytes {
193
206
if last. is_ascii_whitespace ( ) {
194
207
bytes = rest;
@@ -338,6 +351,12 @@ impl<'a> fmt::Debug for EscapeAscii<'a> {
338
351
#[ doc( hidden) ]
339
352
#[ inline]
340
353
pub const fn is_ascii_simple ( mut bytes : & [ u8 ] ) -> bool {
354
+ #[ cfg( kani) ]
355
+ let on_entry_bytes = bytes;
356
+ #[ safety:: loop_invariant(
357
+ bytes. len( ) <= on_entry_bytes. len( ) &&
358
+ ( bytes. len( ) == 0 || bytes. as_ptr( ) == on_entry_bytes. as_ptr( ) )
359
+ ) ]
341
360
while let [ rest @ .., last] = bytes {
342
361
if !last. is_ascii ( ) {
343
362
break ;
@@ -536,4 +555,29 @@ pub mod verify {
536
555
}
537
556
}
538
557
}
558
+
559
+ #[ kani:: proof]
560
+ pub fn check_trim_ascii_start ( ) {
561
+ let a: [ u8 ; 100 ] = kani:: any ( ) ;
562
+ let _ret = a. trim_ascii_start ( ) ;
563
+ }
564
+
565
+ #[ kani:: proof]
566
+ pub fn check_eq_ignore_ascii_case ( ) {
567
+ let a: [ u8 ; 100 ] = kani:: any ( ) ;
568
+ let b: [ u8 ; 100 ] = kani:: any ( ) ;
569
+ let _ret = a. eq_ignore_ascii_case ( b. as_slice ( ) ) ;
570
+ }
571
+
572
+ #[ kani:: proof]
573
+ fn check_is_ascii_simple ( ) {
574
+ let mut bytes: [ u8 ; 100 ] = kani:: any ( ) ;
575
+ let _ret = bytes. is_ascii_simple ( ) ;
576
+ }
577
+
578
+ #[ kani:: proof]
579
+ fn check_trim_ascii_end ( ) {
580
+ let mut a: [ u8 ; 100 ] = kani:: any ( ) ;
581
+ let _ret = a. trim_ascii_end ( ) ;
582
+ }
539
583
}
0 commit comments