-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathgenerics.rs
138 lines (113 loc) · 3.38 KB
/
generics.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#![feature(rustc_private)]
#[macro_use]
mod common;
use common::*;
test_verify_one_file! {
#[test] const_generic verus_code! {
#[verifier(external_body)]
#[verifier::accept_recursive_types(A)]
struct Array<A, const N: usize>([A; N]);
#[verifier(external_body)]
fn array_index<'a, A, const N: usize>(arr: &'a Array<A, N>, i: usize) -> &'a A {
&arr.0[i]
}
impl<A, const N: usize> Array<A, N> {
spec fn array_len(&self) -> usize { N }
}
spec fn f<const A: usize>() -> int { A as int }
spec fn g<const A: usize>() -> int { f::<A>() }
proof fn h() {
let x = g::<7>();
assert(x == 7);
}
proof fn h2() {
let x = g::<7>();
assert(x == 8); // FAILS
}
fn test_arr_len(arr: &Array<u8, 100>) {
assert(arr.array_len() == 100);
}
fn test_arr_len2(arr: &Array<u8, 100>) {
assert(arr.array_len() == 101); // FAILS
}
} => Err(e) => assert_fails(e, 2)
}
test_verify_one_file! {
#[test] test_decorated_types verus_code! {
spec fn sizeof<A>() -> nat;
proof fn test() {
assert(sizeof::<&u8>() == sizeof::<u8>()); // FAILS
}
} => Err(e) => assert_one_fails(e)
}
test_verify_one_file! {
#[test] test_decorated_datatype_encodings verus_code! {
// https://github.com/verus-lang/verus/issues/758
mod m {
pub(crate) struct Seq<A>(A);
}
use crate::m::*;
struct S;
spec fn f<B>(s: Seq<&S>) -> Seq<B>;
proof fn test(x: Seq<&S>) {
let b = f::<S>(x);
}
} => Ok(())
}
test_verify_one_file! {
#[test] test_generic_primitive_has_type verus_code! {
// https://github.com/verus-lang/verus/issues/1221
use vstd::prelude::*;
struct Node { }
struct Data<T: 'static> {
x: int,
y: &'static [T],
}
#[verifier::accept_recursive_types(T)]
#[verifier::external_body]
struct Obj<T> { t: T }
impl<T> Obj<T> {
spec fn view(&self) -> Data<T>;
}
fn test(x: &mut Obj<Node>)
ensures [email protected]@.len() == old(x)@[email protected](),
{
}
fn test2(x: Obj<Node>) {
let ghost j = [email protected];
let mut x2 = x;
test(&mut x2);
let ghost h = [email protected];
assert([email protected]() == [email protected]());
}
} => Ok(())
}
test_verify_one_file! {
#[test] const_generics_int_ranges verus_code! {
proof fn test<const N : u8>() {
assert (0 <= N);
assert (N <= 255);
}
proof fn test2<const N : u8>() {
assert (N < 255); // FAILS
}
proof fn test3<const N : usize>() {
assert (0 <= N);
assert (N <= usize::MAX);
}
} => Err(e) => assert_one_fails(e)
}
test_verify_one_file! {
#[test] const_generics_broadcast verus_code! {
pub open spec fn stuff(t: int) -> bool { true }
#[verifier::external_body]
pub broadcast proof fn broadcaster<const X: u8>()
ensures #[trigger] stuff(X as int) ==> 0 <= X < 255
{
}
fn moo(z: u16) {
assert(stuff(z as int));
assert(z < 255); // FAILS
}
} => Err(e) => assert_one_fails(e)
}