@@ -36,6 +36,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option<usize> {
3636 let mut i = 0 ;
3737
3838 // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`.
39+ #[ safety:: loop_invariant( true ) ]
3940 while i < text. len ( ) {
4041 if text[ i] == x {
4142 return Some ( i) ;
@@ -78,6 +79,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option<usize> {
7879
7980 // search the body of the text
8081 let repeated_x = usize :: repeat_u8( x) ;
82+ #[ safety:: loop_invariant( true ) ]
8183 while offset <= len - 2 * USIZE_BYTES {
8284 // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes
8385 // between the offset and the end of the slice.
@@ -139,6 +141,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
139141 let repeated_x = usize:: repeat_u8 ( x) ;
140142 let chunk_bytes = size_of :: < Chunk > ( ) ;
141143
144+ #[ safety:: loop_invariant( true ) ]
142145 while offset > min_aligned_offset {
143146 // SAFETY: offset starts at len - suffix.len(), as long as it is greater than
144147 // min_aligned_offset (prefix.len()) the remaining distance is at least 2 * chunk_bytes.
@@ -159,3 +162,30 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
159162 // Find the byte before the point the body loop stopped.
160163 text[ ..offset] . iter ( ) . rposition ( |elt| * elt == x)
161164}
165+
166+ #[ cfg( kani) ]
167+ #[ unstable( feature = "kani" , issue = "none" ) ]
168+ pub mod verify {
169+ use super :: * ;
170+
171+ #[ kani:: proof]
172+ #[ cfg( not( all( target_arch = "x86_64" , target_feature = "sse2" ) ) ) ]
173+ pub fn check_memchr_naive ( ) {
174+ const ARR_SIZE : usize = 1000 ;
175+ let x: u8 = kani:: any ( ) ;
176+ let a: [ u8 ; ARR_SIZE ] = kani:: any ( ) ;
177+ let text = kani:: slice:: any_slice_of_array ( & a) ;
178+ let _result = memchr_naive ( x, text) ;
179+ }
180+
181+ #[ kani:: proof]
182+ #[ cfg( not( all( target_arch = "x86_64" , target_feature = "sse2" ) ) ) ]
183+ pub fn check_memchr_naive ( ) {
184+ const ARR_SIZE : usize = 1000 ;
185+ let x: u8 = kani:: any ( ) ;
186+ let a: [ u8 ; ARR_SIZE ] = kani:: any ( ) ;
187+ let text = kani:: slice:: any_slice_of_array ( & a) ;
188+ let _result = memrchr ( x, text) ;
189+ }
190+
191+ }
0 commit comments