From e10a8f6954be2f82ec8da3489fc19c909fb0ae1b Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 28 Jul 2025 10:37:36 -0700 Subject: [PATCH 01/16] add loop-invariants and harnesses --- library/core/src/slice/memchr.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 1e1053583a617..5c7b6c03e127c 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -36,6 +36,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`. + #[safety::loop_invariant(true)] while i < text.len() { if text[i] == x { return Some(i); @@ -78,6 +79,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); + #[safety::loop_invariant(true)] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. @@ -139,6 +141,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { let repeated_x = usize::repeat_u8(x); let chunk_bytes = size_of::(); + #[safety::loop_invariant(true)] while offset > min_aligned_offset { // SAFETY: offset starts at len - suffix.len(), as long as it is greater than // 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 { // Find the byte before the point the body loop stopped. text[..offset].iter().rposition(|elt| *elt == x) } + +#[cfg(kani)] +#[unstable(feature = "kani", issue = "none")] +pub mod verify { + use super::*; + + #[kani::proof] + #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] + pub fn check_memchr_naive() { + const ARR_SIZE: usize = 1000; + let x: u8 = kani::any(); + let a: [u8; ARR_SIZE] = kani::any(); + let text = kani::slice::any_slice_of_array(&a); + let _result = memchr_naive(x, text); + } + + #[kani::proof] + #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] + pub fn check_memchr_naive() { + const ARR_SIZE: usize = 1000; + let x: u8 = kani::any(); + let a: [u8; ARR_SIZE] = kani::any(); + let text = kani::slice::any_slice_of_array(&a); + let _result = memrchr(x, text); + } + +} From 8f02ac9bcca7b74bc190c5c823b07a9c53c063f5 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 28 Jul 2025 10:57:23 -0700 Subject: [PATCH 02/16] format fix --- library/core/src/slice/memchr.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 5c7b6c03e127c..d2dcea9acf177 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -172,7 +172,7 @@ pub mod verify { #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] pub fn check_memchr_naive() { const ARR_SIZE: usize = 1000; - let x: u8 = kani::any(); + let x: u8 = kani::any(); let a: [u8; ARR_SIZE] = kani::any(); let text = kani::slice::any_slice_of_array(&a); let _result = memchr_naive(x, text); @@ -182,10 +182,9 @@ pub mod verify { #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] pub fn check_memchr_naive() { const ARR_SIZE: usize = 1000; - let x: u8 = kani::any(); + let x: u8 = kani::any(); let a: [u8; ARR_SIZE] = kani::any(); let text = kani::slice::any_slice_of_array(&a); let _result = memrchr(x, text); } - } From 617804e4e23be2943ef6044e4aa29f04c2abfddb Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 28 Jul 2025 15:24:27 -0700 Subject: [PATCH 03/16] fix harness name --- library/core/src/slice/memchr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index d2dcea9acf177..c9e1d70c0065e 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -180,7 +180,7 @@ pub mod verify { #[kani::proof] #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] - pub fn check_memchr_naive() { + pub fn check_memchr() { const ARR_SIZE: usize = 1000; let x: u8 = kani::any(); let a: [u8; ARR_SIZE] = kani::any(); From dcf1882b4361437a0e0c17fa70ebd9c3435afa80 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 29 Jul 2025 12:47:17 -0700 Subject: [PATCH 04/16] add crate::kani --- library/core/src/slice/memchr.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index c9e1d70c0065e..d4c900997b0b7 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -167,7 +167,8 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { #[unstable(feature = "kani", issue = "none")] pub mod verify { use super::*; - + use crate::kani; + #[kani::proof] #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] pub fn check_memchr_naive() { From 5ccddc7fac5eecd1067f45e0cda4eeebe495d8b1 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 29 Jul 2025 13:27:16 -0700 Subject: [PATCH 05/16] fix format --- library/core/src/slice/memchr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index d4c900997b0b7..d993ca5e5664e 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -168,7 +168,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { pub mod verify { use super::*; use crate::kani; - + #[kani::proof] #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] pub fn check_memchr_naive() { From 484437753c08112b8d7c7dc474abf8295677d6d6 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 29 Jul 2025 13:35:08 -0700 Subject: [PATCH 06/16] fix format --- library/core/src/slice/memchr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index d993ca5e5664e..606ae0dd42e46 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -79,7 +79,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); - #[safety::loop_invariant(true)] + #[safety::loop_invariant(len >= 2 * USIZE_BYTES)] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. From ce548520d871dc7a51524a959d46e308852c8ff0 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 29 Jul 2025 13:42:27 -0700 Subject: [PATCH 07/16] fix invariant --- library/core/src/slice/memchr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 606ae0dd42e46..57e8714fcd64b 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -79,7 +79,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); - #[safety::loop_invariant(len >= 2 * USIZE_BYTES)] + #[safety::loop_invariant(len >= 2 * USIZE_BYTES && )] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. From 9bd7cc239f881468cb80691cc9a7a3323bee4511 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Tue, 29 Jul 2025 13:57:53 -0700 Subject: [PATCH 08/16] fix invariant --- library/core/src/slice/memchr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 57e8714fcd64b..f181d2b314f59 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -79,7 +79,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); - #[safety::loop_invariant(len >= 2 * USIZE_BYTES && )] + #[safety::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len)] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. From da0761a9645f2db3cb696a7d7e3d1f9eccb77344 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 1 Aug 2025 15:15:03 -0700 Subject: [PATCH 09/16] add quantifiers to loop invariant --- library/core/src/slice/memchr.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index f181d2b314f59..32370ac8842fe 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -36,7 +36,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`. - #[safety::loop_invariant(true)] + #[safety::loop_invariant(i <= text.len() && kani::forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] while i < text.len() { if text[i] == x { return Some(i); @@ -79,7 +79,8 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); - #[safety::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len)] + #[safety::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len && + kani::forall!(|j in (0,offset)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. @@ -170,22 +171,21 @@ pub mod verify { use crate::kani; #[kani::proof] + #[kani::solver(cvc5)] #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] pub fn check_memchr_naive() { - const ARR_SIZE: usize = 1000; + const ARR_SIZE: usize = 64; let x: u8 = kani::any(); - let a: [u8; ARR_SIZE] = kani::any(); - let text = kani::slice::any_slice_of_array(&a); - let _result = memchr_naive(x, text); + let text: [u8; ARR_SIZE] = kani::any(); + let _result = memchr_naive(x, &text); } #[kani::proof] #[cfg(not(all(target_arch = "x86_64", target_feature = "sse2")))] pub fn check_memchr() { - const ARR_SIZE: usize = 1000; + const ARR_SIZE: usize = 64; let x: u8 = kani::any(); - let a: [u8; ARR_SIZE] = kani::any(); - let text = kani::slice::any_slice_of_array(&a); - let _result = memrchr(x, text); + let text: [u8; ARR_SIZE] = kani::any(); + let _result = memrchr(x, &text); } } From 67098c5a562e46cd63673850e59ba08ceaff4627 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 4 Aug 2025 07:37:31 -0700 Subject: [PATCH 10/16] add im port kani --- library/core/src/slice/memchr.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 32370ac8842fe..d42ce66957a02 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -2,6 +2,7 @@ // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch use crate::intrinsics::const_eval_select; +use crate::kani; const LO_USIZE: usize = usize::repeat_u8(0x01); const HI_USIZE: usize = usize::repeat_u8(0x80); @@ -36,7 +37,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`. - #[safety::loop_invariant(i <= text.len() && kani::forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] + #[kani::loop_invariant(i <= text.len() && kani::forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] while i < text.len() { if text[i] == x { return Some(i); @@ -79,7 +80,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); - #[safety::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len && + #[kani::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len && kani::forall!(|j in (0,offset)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes @@ -142,7 +143,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { let repeated_x = usize::repeat_u8(x); let chunk_bytes = size_of::(); - #[safety::loop_invariant(true)] + #[kani::loop_invariant(true)] while offset > min_aligned_offset { // SAFETY: offset starts at len - suffix.len(), as long as it is greater than // min_aligned_offset (prefix.len()) the remaining distance is at least 2 * chunk_bytes. @@ -168,7 +169,6 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { #[unstable(feature = "kani", issue = "none")] pub mod verify { use super::*; - use crate::kani; #[kani::proof] #[kani::solver(cvc5)] From abda27abc9e0b06045ec9cc0d0acd80312d04147 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 4 Aug 2025 07:46:37 -0700 Subject: [PATCH 11/16] add cfg kani --- library/core/src/slice/memchr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index d42ce66957a02..88533f9548b4f 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -2,6 +2,7 @@ // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch use crate::intrinsics::const_eval_select; +#[cfg(kani)] use crate::kani; const LO_USIZE: usize = usize::repeat_u8(0x01); From 864098ff3497c9c6cf3457979deaffa3dc9efe75 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Fri, 15 Aug 2025 12:40:08 -0700 Subject: [PATCH 12/16] add -Z quantifiers --- scripts/run-kani.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/run-kani.sh b/scripts/run-kani.sh index 7714a813cc0bb..1a7c2b36bfd57 100755 --- a/scripts/run-kani.sh +++ b/scripts/run-kani.sh @@ -84,7 +84,7 @@ REPO_URL=${KANI_REPO_URL:-$DEFAULT_REPO_URL} BRANCH_NAME=${KANI_BRANCH_NAME:-$DEFAULT_BRANCH_NAME} # Unstable arguments to pass to Kani -unstable_args="-Z function-contracts -Z mem-predicates -Z float-lib -Z c-ffi -Z loop-contracts" +unstable_args="-Z function-contracts -Z mem-predicates -Z float-lib -Z c-ffi -Z loop-contracts -Z quantifiers" # Variables used for parallel harness verification # When we say "parallel," we mean two dimensions of parallelization: From ab64f85db78d3c3e4a300446785255e970ad8005 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 15 Aug 2025 22:46:15 +0200 Subject: [PATCH 13/16] Make forall compile --- library/core/src/slice/memchr.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 88533f9548b4f..34f541b6b465d 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -3,6 +3,8 @@ use crate::intrinsics::const_eval_select; #[cfg(kani)] +use crate::forall; +#[cfg(kani)] use crate::kani; const LO_USIZE: usize = usize::repeat_u8(0x01); @@ -38,7 +40,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`. - #[kani::loop_invariant(i <= text.len() && kani::forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] + #[kani::loop_invariant(i <= text.len() && forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] while i < text.len() { if text[i] == x { return Some(i); @@ -82,7 +84,7 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); #[kani::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len && - kani::forall!(|j in (0,offset)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] + forall!(|j in (0,offset)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. From b701f3a7cdb96340f9f922f9eb241ed0f0008b11 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Fri, 15 Aug 2025 22:54:53 +0200 Subject: [PATCH 14/16] Fix formatting, make flux happy --- library/core/src/slice/memchr.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs index 34f541b6b465d..6f6cf17f30046 100644 --- a/library/core/src/slice/memchr.rs +++ b/library/core/src/slice/memchr.rs @@ -1,9 +1,9 @@ // Original implementation taken from rust-memchr. // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch -use crate::intrinsics::const_eval_select; #[cfg(kani)] use crate::forall; +use crate::intrinsics::const_eval_select; #[cfg(kani)] use crate::kani; @@ -40,7 +40,7 @@ const fn memchr_naive(x: u8, text: &[u8]) -> Option { let mut i = 0; // FIXME(const-hack): Replace with `text.iter().pos(|c| *c == x)`. - #[kani::loop_invariant(i <= text.len() && forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] + #[cfg_attr(kani, kani::loop_invariant(i <= text.len() && forall!(|j in (0,i)| unsafe {*text.as_ptr().wrapping_add(j)} != x)))] while i < text.len() { if text[i] == x { return Some(i); @@ -83,8 +83,8 @@ const fn memchr_aligned(x: u8, text: &[u8]) -> Option { // search the body of the text let repeated_x = usize::repeat_u8(x); - #[kani::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len && - forall!(|j in (0,offset)| unsafe {*text.as_ptr().wrapping_add(j)} != x))] + #[cfg_attr(kani, kani::loop_invariant(len >= 2 * USIZE_BYTES && offset <= len && + forall!(|j in (0,offset)| unsafe {*text.as_ptr().wrapping_add(j)} != x)))] while offset <= len - 2 * USIZE_BYTES { // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes // between the offset and the end of the slice. @@ -146,7 +146,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option { let repeated_x = usize::repeat_u8(x); let chunk_bytes = size_of::(); - #[kani::loop_invariant(true)] + #[cfg_attr(kani, kani::loop_invariant(true))] while offset > min_aligned_offset { // SAFETY: offset starts at len - suffix.len(), as long as it is greater than // min_aligned_offset (prefix.len()) the remaining distance is at least 2 * chunk_bytes. From e5515d635a3ac526cdc745aa861a14821d92c713 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Aug 2025 09:59:12 -0700 Subject: [PATCH 15/16] change unwind to solver(cvc5) --- library/core/src/ffi/c_str.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 756237c6f4182..8cd6397ff12f2 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -891,7 +891,7 @@ mod verify { // pub const fn from_bytes_until_nul(bytes: &[u8]) -> Result<&CStr, FromBytesUntilNulError> #[kani::proof] - #[kani::unwind(32)] // 7.3 seconds when 16; 33.1 seconds when 32 + #[kani::solver(cvc5)] // 7.3 seconds when 16; 33.1 seconds when 32 fn check_from_bytes_until_nul() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -907,7 +907,7 @@ mod verify { // pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr #[kani::proof_for_contract(CStr::from_bytes_with_nul_unchecked)] - #[kani::unwind(33)] + #[kani::solver(cvc5)] fn check_from_bytes_with_nul_unchecked() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -926,7 +926,7 @@ mod verify { // pub fn bytes(&self) -> Bytes<'_> #[kani::proof] - #[kani::unwind(32)] + #[kani::solver(cvc5)] fn check_bytes() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -944,7 +944,7 @@ mod verify { // pub const fn to_str(&self) -> Result<&str, str::Utf8Error> #[kani::proof] - #[kani::unwind(32)] + #[kani::solver(cvc5)] fn check_to_str() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -988,7 +988,7 @@ mod verify { // pub const fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> #[kani::proof] - #[kani::unwind(17)] + #[kani::solver(cvc5)] fn check_from_bytes_with_nul() { const MAX_SIZE: usize = 16; let string: [u8; MAX_SIZE] = kani::any(); @@ -1027,7 +1027,7 @@ mod verify { // pub const fn to_bytes(&self) -> &[u8] #[kani::proof] - #[kani::unwind(32)] + #[kani::solver(cvc5)] fn check_to_bytes() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -1072,7 +1072,7 @@ mod verify { // pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr #[kani::proof_for_contract(CStr::from_ptr)] - #[kani::unwind(33)] + #[kani::solver(cvc5)] fn check_from_ptr_contract() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -1085,7 +1085,7 @@ mod verify { // pub const fn is_empty(&self) -> bool #[kani::proof] - #[kani::unwind(33)] + #[kani::solver(cvc5)] fn check_is_empty() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); From a96b0959a976d9dabfed5c98e3bac76b4eeffca0 Mon Sep 17 00:00:00 2001 From: thanhnguyen-aws Date: Mon, 18 Aug 2025 10:30:46 -0700 Subject: [PATCH 16/16] change unwind to solver(cvc5) --- library/core/src/ffi/c_str.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 8cd6397ff12f2..a674f050f285a 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -961,7 +961,7 @@ mod verify { // pub const fn as_ptr(&self) -> *const c_char #[kani::proof] - #[kani::unwind(33)] + #[kani::solver(cvc5)] fn check_as_ptr() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -1002,7 +1002,7 @@ mod verify { // pub const fn count_bytes(&self) -> usize #[kani::proof] - #[kani::unwind(32)] + #[kani::solver(cvc5)] fn check_count_bytes() { const MAX_SIZE: usize = 32; let mut bytes: [u8; MAX_SIZE] = kani::any(); @@ -1043,7 +1043,7 @@ mod verify { // pub const fn to_bytes_with_nul(&self) -> &[u8] #[kani::proof] - #[kani::unwind(33)] + #[kani::solver(cvc5)] fn check_to_bytes_with_nul() { const MAX_SIZE: usize = 32; let string: [u8; MAX_SIZE] = kani::any(); @@ -1059,7 +1059,7 @@ mod verify { // const unsafe fn strlen(ptr: *const c_char) -> usize #[kani::proof_for_contract(super::strlen)] - #[kani::unwind(33)] + #[kani::solver(cvc5)] fn check_strlen_contract() { const MAX_SIZE: usize = 32; let mut string: [u8; MAX_SIZE] = kani::any();