1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{
4 invariant::*,
5 logic::ops::IndexLogic,
6 std::{
7 ops::{Deref, DerefMut, Index, IndexMut},
8 slice::SliceIndex,
9 },
10 *,
11};
12#[cfg(feature = "nightly")]
13use ::std::alloc::Allocator;
14pub use ::std::vec::*;
15
16#[cfg(feature = "nightly")]
17impl<T, A: Allocator> View for Vec<T, A> {
18 type ViewTy = Seq<T>;
19
20 #[trusted]
21 #[logic(opaque)]
22 #[ensures(result.len() <= usize::MAX@)]
23 fn view(self) -> Seq<T> {
24 dead
25 }
26}
27
28#[cfg(feature = "nightly")]
29impl<T: DeepModel, A: Allocator> DeepModel for Vec<T, A> {
30 type DeepModelTy = Seq<T::DeepModelTy>;
31
32 #[trusted]
33 #[logic(opaque)]
34 #[ensures(self.view().len() == result.len())]
35 #[ensures(forall<i> 0 <= i && i < self.view().len()
36 ==> result[i] == self[i].deep_model())]
37 fn deep_model(self) -> Self::DeepModelTy {
38 dead
39 }
40}
41
42#[cfg(feature = "nightly")]
43impl<T, A: Allocator> IndexLogic<Int> for Vec<T, A> {
44 type Item = T;
45
46 #[logic(open, inline)]
47 fn index_logic(self, ix: Int) -> Self::Item {
48 pearlite! { self@[ix] }
49 }
50}
51
52#[cfg(feature = "nightly")]
53impl<T, A: Allocator> IndexLogic<usize> for Vec<T, A> {
54 type Item = T;
55
56 #[logic(open, inline)]
57 fn index_logic(self, ix: usize) -> Self::Item {
58 pearlite! { self@[ix@] }
59 }
60}
61
62#[cfg(not(feature = "nightly"))]
64impl<T> IndexLogic<Int> for Vec<T> {
65 type Item = T;
66}
67
68#[cfg(not(feature = "nightly"))]
69impl<T> IndexLogic<usize> for Vec<T> {
70 type Item = T;
71}
72
73#[cfg(feature = "nightly")]
74impl<T, A: Allocator> Resolve for Vec<T, A> {
75 #[logic(open, prophetic, inline)]
76 fn resolve(self) -> bool {
77 pearlite! { forall<i> 0 <= i && i < self@.len() ==> resolve(self[i]) }
78 }
79
80 #[trusted]
81 #[logic(prophetic)]
82 #[requires(structural_resolve(self))]
83 #[ensures(self.resolve())]
84 fn resolve_coherence(self) {}
85}
86
87#[cfg(feature = "nightly")]
88impl<T, A: Allocator> Invariant for Vec<T, A> {
89 #[logic(open, prophetic)]
90 #[creusot::trusted_ignore_structural_inv]
91 #[creusot::trusted_is_tyinv_trivial_if_param_trivial]
92 fn invariant(self) -> bool {
93 pearlite! { invariant::inv(self@) }
94 }
95}
96
97extern_spec! {
98 mod std {
99 mod vec {
100 impl<T> Vec<T> {
101 #[check(ghost)]
102 #[ensures(result@.len() == 0)]
103 fn new() -> Vec<T>;
104
105 #[check(terminates)] #[ensures(result@.len() == 0)]
107 fn with_capacity(capacity: usize) -> Vec<T>;
108 }
109 impl<T, A: Allocator> Vec<T, A> {
110 #[check(ghost)]
111 #[ensures(result@ == self@.len())]
112 fn len(&self) -> usize;
113
114 #[check(terminates)] #[ensures((^self)@ == self@.push_back(v))]
116 fn push(&mut self, v: T);
117
118 #[check(ghost)]
119 #[ensures(match result {
120 Some(t) =>
121 (^self)@ == self@.subsequence(0, self@.len() - 1) &&
122 self@ == (^self)@.push_back(t),
123 None => *self == ^self && self@.len() == 0
124 })]
125 fn pop(&mut self) -> Option<T>;
126
127 #[check(ghost)]
128 #[requires(ix@ < self@.len())]
129 #[ensures(result == self[ix@])]
130 #[ensures((^self)@ == self@.subsequence(0, ix@).concat(self@.subsequence(ix@ + 1, self@.len())))]
131 #[ensures((^self)@.len() == self@.len() - 1)]
132 fn remove(&mut self, ix: usize) -> T;
133
134 #[check(terminates)] #[ensures((^self)@.len() == self@.len() + 1)]
136 #[ensures(forall<i> 0 <= i && i < index@ ==> (^self)[i] == self[i])]
137 #[ensures((^self)[index@] == element)]
138 #[ensures(forall<i> index@ < i && i < (^self)@.len() ==> (^self)[i] == self[i - 1])]
139 fn insert(&mut self, index: usize, element: T);
140
141 #[check(ghost)]
142 #[ensures(result@ >= self@.len())]
143 fn capacity(&self) -> usize;
144
145 #[check(terminates)] #[ensures((^self)@ == self@)]
147 fn reserve(&mut self, additional: usize);
148
149 #[check(terminates)] #[ensures((^self)@ == self@)]
151 fn reserve_exact(&mut self, additional: usize);
152
153 #[check(ghost)]
154 #[ensures((^self)@ == self@)]
155 fn shrink_to_fit(&mut self);
156
157 #[check(ghost)]
158 #[ensures((^self)@ == self@)]
159 fn shrink_to(&mut self, min_capacity: usize);
160
161 #[check(ghost)]
162 #[ensures((^self)@.len() == 0)]
163 fn clear(&mut self);
164 }
165
166 impl<T, A: Allocator> Extend<T> for Vec<T, A> {
167 #[requires(I::into_iter.precondition((iter,)))]
168 #[ensures(exists<start_: I::IntoIter, done: &mut I::IntoIter, prod: Seq<T>>
169 inv(start_) && inv(done) && inv(prod) &&
170 I::into_iter.postcondition((iter,), start_) &&
171 done.completed() && start_.produces(prod, *done) && (^self)@ == self@.concat(prod)
172 )]
173 fn extend<I>(&mut self, iter: I)
174 where
175 I: IntoIterator<Item = T>, I::IntoIter: Iterator;
176 }
177
178 impl<T, I: SliceIndex<[T]>, A: Allocator> IndexMut<I> for Vec<T, A> {
179 #[check(ghost)]
180 #[requires(ix.in_bounds(self@))]
181 #[ensures(ix.has_value(self@, *result))]
182 #[ensures(ix.has_value((^self)@, ^result))]
183 #[ensures(ix.resolve_elswhere(self@, (^self)@))]
184 #[ensures((^self)@.len() == self@.len())]
185 fn index_mut(&mut self, ix: I) -> &mut <Vec<T, A> as Index<I>>::Output;
186 }
187
188 impl<T, I: SliceIndex<[T]>, A: Allocator> Index<I> for Vec<T, A> {
189 #[check(ghost)]
190 #[requires(ix.in_bounds(self@))]
191 #[ensures(ix.has_value(self@, *result))]
192 fn index(&self, ix: I) -> & <Vec<T, A> as Index<I>>::Output;
193 }
194
195 impl<T, A: Allocator> Deref for Vec<T, A> {
196 #[check(ghost)]
197 #[ensures(result@ == self@)]
198 fn deref(&self) -> &[T];
199 }
200
201 impl<T, A: Allocator> DerefMut for Vec<T, A> {
202 #[check(ghost)]
203 #[ensures(result@ == self@)]
204 #[ensures((^result)@ == (^self)@)]
205 fn deref_mut(&mut self) -> &mut [T];
206 }
207
208 #[ensures(result@.len() == n@)]
209 #[ensures(forall<i> 0 <= i && i < n@ ==> result[i] == elem)]
210 fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T>;
211 }
212 }
213
214 impl<T, A: Allocator> IntoIterator for Vec<T, A> {
215 #[check(ghost)]
216 #[ensures(self@ == result@)]
217 fn into_iter(self) -> IntoIter<T, A>;
218 }
219
220 impl<'a, T, A: Allocator> IntoIterator for &'a Vec<T, A> {
221 #[check(ghost)]
222 #[ensures(self@ == result@@)]
223 fn into_iter(self) -> std::slice::Iter<'a, T>;
224 }
225
226 impl<'a, T, A: Allocator> IntoIterator for &'a mut Vec<T, A> {
227 #[check(ghost)]
228 #[ensures(self@ == result@@)]
229 fn into_iter(self) -> std::slice::IterMut<'a, T>;
230 }
231
232 impl<T> Default for Vec<T> {
233 #[check(ghost)]
234 #[ensures(result@ == Seq::empty())]
235 fn default() -> Vec<T>;
236 }
237
238 impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> {
239 #[ensures(forall<i> 0 <= i && i < self@.len() ==>
240 T::clone.postcondition((&self@[i],), result@[i]))]
241 fn clone(&self) -> Vec<T, A>;
242 }
243}
244
245#[cfg(feature = "nightly")]
246impl<T, A: Allocator> View for std::vec::IntoIter<T, A> {
247 type ViewTy = Seq<T>;
248
249 #[logic(opaque)]
250 fn view(self) -> Self::ViewTy {
251 dead
252 }
253}
254
255#[cfg(feature = "nightly")]
256impl<T, A: Allocator> Resolve for std::vec::IntoIter<T, A> {
257 #[logic(open, prophetic, inline)]
258 fn resolve(self) -> bool {
259 pearlite! { forall<i> 0 <= i && i < self@.len() ==> resolve(self@[i]) }
260 }
261
262 #[trusted]
263 #[logic(prophetic)]
264 #[requires(structural_resolve(self))]
265 #[ensures(self.resolve())]
266 fn resolve_coherence(self) {}
267}
268
269#[cfg(feature = "nightly")]
270impl<T, A: Allocator> Iterator for std::vec::IntoIter<T, A> {
271 #[logic(open, prophetic)]
272 fn completed(&mut self) -> bool {
273 pearlite! { self.resolve() && self@ == Seq::empty() }
274 }
275
276 #[logic(open)]
277 fn produces(self, visited: Seq<T>, rhs: Self) -> bool {
278 pearlite! {
279 self@ == visited.concat(rhs@)
280 }
281 }
282
283 #[logic(open, law)]
284 #[ensures(self.produces(Seq::empty(), self))]
285 fn produces_refl(self) {}
286
287 #[logic(open, law)]
288 #[requires(a.produces(ab, b))]
289 #[requires(b.produces(bc, c))]
290 #[ensures(a.produces(ab.concat(bc), c))]
291 fn produces_trans(a: Self, ab: Seq<T>, b: Self, bc: Seq<T>, c: Self) {}
292}
293
294impl<T> FromIterator<T> for Vec<T> {
295 #[logic(open)]
296 fn from_iter_post(prod: Seq<T>, res: Self) -> bool {
297 pearlite! { prod == res@ }
298 }
299}
300
301#[cfg(not(feature = "nightly"))]
303mod impls {
304 use super::*;
305 impl<T> View for Vec<T> {
306 type ViewTy = Seq<T>;
307 }
308
309 impl<T: DeepModel> DeepModel for Vec<T> {
310 type DeepModelTy = Seq<T::DeepModelTy>;
311 }
312 impl<T> Resolve for Vec<T> {}
313 impl<T> Invariant for Vec<T> {}
314 impl<T> View for std::vec::IntoIter<T> {
315 type ViewTy = Seq<T>;
316 }
317 impl<T> Resolve for std::vec::IntoIter<T> {}
318 impl<T> Iterator for std::vec::IntoIter<T> {}
319}