diff --git a/source/rust_verify_test/tests/slices.rs b/source/rust_verify_test/tests/slices.rs index ef8c102533..ae1d18834b 100644 --- a/source/rust_verify_test/tests/slices.rs +++ b/source/rust_verify_test/tests/slices.rs @@ -1156,3 +1156,16 @@ test_verify_one_file! { } } => Ok(()) } + +test_verify_one_file! { + #[test] test_slice_contains verus_code! { + use vstd::prelude::*; + + fn test() { + let values: &[u8] = &[1, 2, 3]; + + assert(values.contains(&2)); + assert(!values.contains(&4)); + } + } => Ok(()) +} diff --git a/source/vstd/std_specs/slice.rs b/source/vstd/std_specs/slice.rs index 2658d31d26..d129b4d58e 100644 --- a/source/vstd/std_specs/slice.rs +++ b/source/vstd/std_specs/slice.rs @@ -327,6 +327,20 @@ impl super::cmp::PartialEqSpecImpl<[U]> for [T] where T: PartialEq + su } } +// contains +pub open spec fn spec_slice_contains>(slice: &[T], value: &T) -> bool { + exists |i: int| #![auto] 0 <= i < slice@.len() + && >::eq_spec(&slice[i], value) +} + +#[verifier::when_used_as_spec(spec_slice_contains)] +pub assume_specification[ <[T]>::contains ] (slice: &[T], value: &T) -> (result: bool) + where + T: PartialEq, + ensures + >::obeys_eq_spec() ==> result == spec_slice_contains(slice, value), +; + // The `iter` method of a `` returns an iterator of type `Iter<'_, T>`, // so we specify that type here. #[verifier::external_type_specification]