vstd/std_specs/
option.rs
1#![allow(unused_imports)]
2use super::super::prelude::*;
3
4use core::option::Option;
5use core::option::Option::None;
6use core::option::Option::Some;
7
8verus! {
9
10impl<T> View for Option<T> {
11 type V = Option<T>;
12
13 open spec fn view(&self) -> Option<T> {
14 *self
15 }
16}
17
18impl<T: DeepView> DeepView for Option<T> {
19 type V = Option<T::V>;
20
21 open spec fn deep_view(&self) -> Option<T::V> {
22 match self {
23 Some(t) => Some(t.deep_view()),
24 None => None,
25 }
26 }
27}
28
29pub trait OptionAdditionalFns<T>: Sized {
31 #[deprecated(note = "is_Variant is deprecated - use `->` or `matches` instead: https://verus-lang.github.io/verus/guide/datatypes_enum.html")]
32 #[allow(non_snake_case)]
33 spec fn is_Some(&self) -> bool;
34
35 #[deprecated(note = "is_Variant is deprecated - use `->` or `matches` instead: https://verus-lang.github.io/verus/guide/datatypes_enum.html")]
36 #[allow(non_snake_case)]
37 spec fn get_Some_0(&self) -> T;
38
39 #[deprecated(note = "is_Variant is deprecated - use `->` or `matches` instead: https://verus-lang.github.io/verus/guide/datatypes_enum.html")]
40 #[allow(non_snake_case)]
41 spec fn is_None(&self) -> bool;
42
43 #[allow(non_snake_case)]
44 spec fn arrow_Some_0(&self) -> T;
45
46 #[allow(non_snake_case)]
47 spec fn arrow_0(&self) -> T;
48
49 spec fn tracked_is_some(&self) -> bool;
51
52 proof fn tracked_unwrap(tracked self) -> (tracked t: T)
53 requires
54 self.tracked_is_some(),
55 ensures
56 t == self->0,
57 ;
58
59 proof fn tracked_expect(tracked self, msg: &str) -> (tracked t: T)
60 requires
61 self.tracked_is_some(),
62 ensures
63 t == self->0,
64 ;
65
66 proof fn tracked_borrow(tracked &self) -> (tracked t: &T)
67 requires
68 self.tracked_is_some(),
69 ensures
70 t == self->0,
71 ;
72
73 proof fn tracked_take(tracked &mut self) -> (tracked t: T)
74 requires
75 old(self).tracked_is_some(),
76 ensures
77 t == old(self)->0,
78 !self.tracked_is_some(),
79 ;
80}
81
82impl<T> OptionAdditionalFns<T> for Option<T> {
83 #[verifier::inline]
84 open spec fn is_Some(&self) -> bool {
85 is_variant(self, "Some")
86 }
87
88 #[verifier::inline]
89 open spec fn get_Some_0(&self) -> T {
90 get_variant_field(self, "Some", "0")
91 }
92
93 #[verifier::inline]
94 open spec fn is_None(&self) -> bool {
95 is_variant(self, "None")
96 }
97
98 #[verifier::inline]
99 open spec fn arrow_Some_0(&self) -> T {
100 get_variant_field(self, "Some", "0")
101 }
102
103 #[verifier::inline]
104 open spec fn arrow_0(&self) -> T {
105 get_variant_field(self, "Some", "0")
106 }
107
108 open spec fn tracked_is_some(&self) -> bool {
109 is_variant(self, "Some")
110 }
111
112 proof fn tracked_unwrap(tracked self) -> (tracked t: T) {
113 match self {
114 Option::Some(t) => t,
115 Option::None => proof_from_false(),
116 }
117 }
118
119 proof fn tracked_expect(tracked self, msg: &str) -> (tracked t: T) {
120 match self {
121 Option::Some(t) => t,
122 Option::None => proof_from_false(),
123 }
124 }
125
126 proof fn tracked_borrow(tracked &self) -> (tracked t: &T) {
127 match self {
128 Option::Some(t) => t,
129 Option::None => proof_from_false(),
130 }
131 }
132
133 proof fn tracked_take(tracked &mut self) -> (tracked t: T) {
135 let tracked mut x = None::<T>;
136 super::super::modes::tracked_swap(self, &mut x);
137 x.tracked_unwrap()
138 }
139}
140
141#[verifier::inline]
144pub open spec fn is_some<T>(option: &Option<T>) -> bool {
145 is_variant(option, "Some")
146}
147
148#[verifier::when_used_as_spec(is_some)]
149pub assume_specification<T>[ Option::<T>::is_some ](option: &Option<T>) -> (b: bool)
150 ensures
151 b == is_some(option),
152;
153
154#[verifier::inline]
156pub open spec fn is_none<T>(option: &Option<T>) -> bool {
157 is_variant(option, "None")
158}
159
160#[verifier::when_used_as_spec(is_none)]
161pub assume_specification<T>[ Option::<T>::is_none ](option: &Option<T>) -> (b: bool)
162 ensures
163 b == is_none(option),
164;
165
166pub assume_specification<T>[ Option::<T>::as_ref ](option: &Option<T>) -> (a: Option<&T>)
168 ensures
169 a is Some <==> option is Some,
170 a is Some ==> option->0 == a->0,
171;
172
173#[verifier::inline]
175pub open spec fn spec_unwrap<T>(option: Option<T>) -> T
176 recommends
177 option is Some,
178{
179 option->0
180}
181
182#[verifier::when_used_as_spec(spec_unwrap)]
183pub assume_specification<T>[ Option::<T>::unwrap ](option: Option<T>) -> (t: T)
184 requires
185 option is Some,
186 ensures
187 t == spec_unwrap(option),
188;
189
190#[verifier::inline]
192pub open spec fn spec_unwrap_or<T>(option: Option<T>, default: T) -> T {
193 match option {
194 Some(t) => t,
195 None => default,
196 }
197}
198
199#[verifier::when_used_as_spec(spec_unwrap_or)]
200pub assume_specification<T>[ Option::<T>::unwrap_or ](option: Option<T>, default: T) -> (t: T)
201 ensures
202 t == spec_unwrap_or(option, default),
203;
204
205#[verifier::inline]
207pub open spec fn spec_expect<T>(option: Option<T>, msg: &str) -> T
208 recommends
209 option is Some,
210{
211 option->0
212}
213
214#[verifier::when_used_as_spec(spec_expect)]
215pub assume_specification<T>[ Option::<T>::expect ](option: Option<T>, msg: &str) -> (t: T)
216 requires
217 option is Some,
218 ensures
219 t == spec_expect(option, msg),
220;
221
222pub assume_specification<T>[ Option::<T>::take ](option: &mut Option<T>) -> (t: Option<T>)
224 ensures
225 t == old(option),
226 *option is None,
227;
228
229pub assume_specification<T, U, F: FnOnce(T) -> U>[ Option::<T>::map ](a: Option<T>, f: F) -> (ret:
231 Option<U>)
232 requires
233 a.is_some() ==> f.requires((a.unwrap(),)),
234 ensures
235 ret.is_some() == a.is_some(),
236 ret.is_some() ==> f.ensures((a.unwrap(),), ret.unwrap()),
237;
238
239pub assume_specification<T: Clone>[ <Option<T> as Clone>::clone ](opt: &Option<T>) -> (res: Option<
241 T,
242>)
243 ensures
244 opt.is_none() ==> res.is_none(),
245 opt.is_some() ==> res.is_some() && cloned::<T>(opt.unwrap(), res.unwrap()),
246;
247
248#[verifier::inline]
250pub open spec fn spec_ok_or<T, E>(option: Option<T>, err: E) -> Result<T, E> {
251 match option {
252 Some(t) => Ok(t),
253 None => Err(err),
254 }
255}
256
257#[verifier::when_used_as_spec(spec_ok_or)]
258pub assume_specification<T, E>[ Option::ok_or ](option: Option<T>, err: E) -> (res: Result<T, E>)
259 ensures
260 res == spec_ok_or(option, err),
261;
262
263}