@@ -68,6 +68,11 @@ impl [u8] {
6868 let mut a = self ;
6969 let mut b = other;
7070
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+ ) ]
7176 while let ( [ first_a, rest_a @ ..] , [ first_b, rest_b @ ..] ) = ( a, b) {
7277 if first_a. eq_ignore_ascii_case ( & first_b) {
7378 a = rest_a;
@@ -160,6 +165,10 @@ impl [u8] {
160165 let mut bytes = self ;
161166 // Note: A pattern matching based approach (instead of indexing) allows
162167 // 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+ ) ]
163172 while let [ first, rest @ ..] = bytes {
164173 if first. is_ascii_whitespace ( ) {
165174 bytes = rest;
@@ -189,6 +198,10 @@ impl [u8] {
189198 let mut bytes = self ;
190199 // Note: A pattern matching based approach (instead of indexing) allows
191200 // making the function const.
201+ #[ safety:: loop_invariant(
202+ bytes. len( ) <= self . len( ) &&
203+ ( bytes. len( ) == 0 || self . as_ptr( ) == bytes. as_ptr( ) )
204+ ) ]
192205 while let [ rest @ .., last] = bytes {
193206 if last. is_ascii_whitespace ( ) {
194207 bytes = rest;
@@ -338,6 +351,12 @@ impl<'a> fmt::Debug for EscapeAscii<'a> {
338351#[ doc( hidden) ]
339352#[ inline]
340353pub 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+ ) ]
341360 while let [ rest @ .., last] = bytes {
342361 if !last. is_ascii ( ) {
343362 break ;
@@ -536,4 +555,29 @@ pub mod verify {
536555 }
537556 }
538557 }
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+ }
539583}
0 commit comments