Skip to content

Commit db81a74

Browse files
authored
support vec_from_elem; fixes #1952 (#1983)
1 parent b75fd8d commit db81a74

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

source/rust_verify_test/tests/std.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,3 +610,55 @@ test_verify_one_file! {
610610
}
611611
} => Ok(())
612612
}
613+
614+
test_verify_one_file! {
615+
#[test] vec_from_elem verus_code! {
616+
use vstd::prelude::*;
617+
618+
#[derive(Debug)]
619+
pub struct X {
620+
pub u: u64
621+
}
622+
623+
impl Clone for X {
624+
fn clone(&self) -> (s: Self)
625+
ensures s.u == (if self.u < 1000 { self.u + 1 } else { 1000 })
626+
{
627+
X { u: if self.u < 1000 { self.u + 1 } else { 1000 } }
628+
}
629+
}
630+
631+
fn test1() {
632+
let x = X { u: 0 };
633+
let v = vec![x; 4];
634+
assert(v.len() == 4);
635+
assert(v@[0].u == 0 || v@[0].u == 1);
636+
assert(v@[1].u == 0 || v@[1].u == 1);
637+
assert(v@[2].u == 0 || v@[2].u == 1);
638+
assert(v@[3].u == 0 || v@[3].u == 1);
639+
}
640+
641+
fn test2() {
642+
let x = X { u: 0 };
643+
let v = vec![x; 4];
644+
assert(v.len() == 4);
645+
assert(v@[0].u == 0); // FAILS
646+
}
647+
648+
fn test3() {
649+
let x = X { u: 0 };
650+
let v = vec![x; 4];
651+
assert(v.len() == 4);
652+
assert(v@[0].u == 1); // FAILS
653+
}
654+
655+
fn test4() {
656+
let v = vec![12; 4];
657+
assert(v.len() == 4);
658+
assert(v@[0] == 12);
659+
assert(v@[1] == 12);
660+
assert(v@[2] == 12);
661+
assert(v@[3] == 12);
662+
}
663+
} => Err(err) => assert_fails(err, 2)
664+
}

source/vstd/std_specs/vec.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ impl<T, A: Allocator> super::super::pervasive::ForLoopGhostIteratorNew for IntoI
344344
}
345345
}
346346

347+
// This is used by `vec![x; n]`
348+
pub assume_specification<T: Clone>[ alloc::vec::from_elem ](elem: T, n: usize) -> (v: Vec<T>)
349+
ensures
350+
v.len() == n,
351+
forall |i| 0 <= i < n ==> cloned(elem, #[trigger] v@[i]);
352+
347353
impl<T, A: Allocator> super::super::pervasive::ForLoopGhostIterator for IntoIterGhostIterator<
348354
T,
349355
A,

0 commit comments

Comments
 (0)