1#[cfg(creusot)]
2use crate::resolve::structural_resolve;
3use crate::{
4 ghost::perm::Perm, invariant::*, logic::ops::IndexLogic, prelude::*,
5 std::iter::ExactSizeIteratorSpec,
6};
7#[cfg(creusot)]
8use core::ops::{Index, IndexMut};
9use core::{
10 ops::{Bound, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
11 slice::*,
12};
13#[cfg(all(creusot, feature = "std"))]
14use std::alloc::Allocator;
15
16impl<T> Invariant for [T] {
17 #[logic(open, prophetic)]
18 #[creusot::trusted_trivial_if_param_trivial]
19 fn invariant(self) -> bool {
20 pearlite! { inv(self@) }
21 }
22}
23
24impl<T> Resolve for [T] {
25 #[logic(open, prophetic, inline)]
26 #[creusot::trusted_trivial_if_param_trivial]
27 fn resolve(self) -> bool {
28 pearlite! { forall<i> 0 <= i && i < self@.len() ==> resolve(self[i]) }
29 }
30
31 #[trusted]
32 #[logic(prophetic)]
33 #[requires(structural_resolve(self))]
34 #[ensures(self.resolve())]
35 fn resolve_coherence(self) {}
36}
37
38impl<T> View for [T] {
39 type ViewTy = Seq<T>;
40
41 #[logic]
42 #[cfg_attr(target_pointer_width = "16", builtin("creusot.slice.Slice16$BW$.view"))]
43 #[cfg_attr(target_pointer_width = "32", builtin("creusot.slice.Slice32$BW$.view"))]
44 #[cfg_attr(target_pointer_width = "64", builtin("creusot.slice.Slice64$BW$.view"))]
45 fn view(self) -> Self::ViewTy {
46 dead
47 }
48}
49
50impl<T: DeepModel> DeepModel for [T] {
51 type DeepModelTy = Seq<T::DeepModelTy>;
52
53 #[trusted]
54 #[logic(opaque)]
55 #[ensures((&self)@.len() == result.len())]
56 #[ensures(forall<i> 0 <= i && i < result.len() ==> result[i] == (&self)[i].deep_model())]
57 fn deep_model(self) -> Self::DeepModelTy {
58 dead
59 }
60}
61
62impl<T> IndexLogic<Int> for [T] {
63 type Item = T;
64
65 #[logic(open, inline)]
66 fn index_logic(self, ix: Int) -> Self::Item {
67 pearlite! { self@[ix] }
68 }
69}
70
71impl<T> IndexLogic<usize> for [T] {
72 type Item = T;
73
74 #[logic(open, inline)]
75 fn index_logic(self, ix: usize) -> Self::Item {
76 pearlite! { self@[ix@] }
77 }
78}
79
80pub trait SliceExt<T> {
81 #[logic]
82 fn to_mut_seq(&mut self) -> Seq<&mut T>;
83
84 #[logic]
85 fn to_ref_seq(&self) -> Seq<&T>;
86
87 #[check(terminates)]
88 fn as_ptr_perm(&self) -> (*const T, Ghost<&Perm<*const [T]>>);
89
90 #[check(terminates)]
91 fn as_mut_ptr_perm<'a>(&'a mut self) -> (*mut T, Ghost<GuardedBorrow<'a, Perm<*const [T]>>>);
92}
93
94impl<T> SliceExt<T> for [T] {
95 #[trusted]
96 #[logic(opaque)]
97 #[ensures(result.len() == self@.len())]
98 #[ensures(forall<i> 0 <= i && i < result.len() ==> result[i] == &mut self[i])]
99 fn to_mut_seq(&mut self) -> Seq<&mut T> {
101 dead
102 }
103
104 #[trusted]
105 #[logic(opaque)]
106 #[ensures(result.len() == self@.len())]
107 #[ensures(forall<i> 0 <= i && i < result.len() ==> result[i] == &self[i])]
108 fn to_ref_seq(&self) -> Seq<&T> {
109 dead
110 }
111
112 #[check(terminates)]
114 #[ensures(result.0 == *result.1.ward() as *const T)]
115 #[ensures(self == result.1.val_unsized())]
116 #[erasure(Self::as_ptr)]
117 fn as_ptr_perm(&self) -> (*const T, Ghost<&Perm<*const [T]>>) {
118 let (ptr, own) = Perm::from_ref(self);
119 (ptr as *const T, own)
120 }
121
122 #[check(terminates)]
124 #[ensures(result.1.guard() == |b: &mut Perm<*const [T]>| {
125 *b.ward() as *const T == result.0 as *const T &&
126 b.ward().len_logic()@ == self@.len()
127 })]
128 #[ensures(*self == *result.1.borrow.val_unsized())]
129 #[ensures(^self == *(^result.1.borrow).val_unsized())]
130 #[erasure(Self::as_mut_ptr)]
131 fn as_mut_ptr_perm<'a>(&'a mut self) -> (*mut T, Ghost<GuardedBorrow<'a, Perm<*const [T]>>>) {
132 let (ptr, own) = Perm::from_mut(self);
133 (ptr as *mut T, own)
134 }
135}
136
137pub trait SliceIndexSpec<T: ?Sized>: SliceIndex<T>
138where
139 T: View,
140{
141 #[logic]
142 fn in_bounds(self, seq: T::ViewTy) -> bool;
143
144 #[logic]
145 fn has_value(self, seq: T::ViewTy, out: Self::Output) -> bool;
146
147 #[logic]
148 fn resolve_elswhere(self, old: T::ViewTy, fin: T::ViewTy) -> bool;
149}
150
151impl<T> SliceIndexSpec<[T]> for usize {
152 #[logic(open, inline)]
153 fn in_bounds(self, seq: Seq<T>) -> bool {
154 pearlite! { self@ < seq.len() }
155 }
156
157 #[logic(open, inline)]
158 fn has_value(self, seq: Seq<T>, out: T) -> bool {
159 pearlite! { seq[self@] == out }
160 }
161
162 #[logic(open, inline)]
163 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
164 pearlite! { forall<i> 0 <= i && i != self@ && i < old.len() ==> old[i] == fin[i] }
165 }
166}
167
168impl<T> SliceIndexSpec<[T]> for Range<usize> {
169 #[logic(open)]
170 fn in_bounds(self, seq: Seq<T>) -> bool {
171 pearlite! { self.start@ <= self.end@ && self.end@ <= seq.len() }
172 }
173
174 #[logic(open)]
175 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
176 pearlite! { seq.subsequence(self.start@, self.end@) == out@ }
177 }
178
179 #[logic(open)]
180 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
181 pearlite! {
182 forall<i> 0 <= i && (i < self.start@ || self.end@ <= i) && i < old.len()
183 ==> old[i] == fin[i]
184 }
185 }
186}
187
188impl<T> SliceIndexSpec<[T]> for RangeInclusive<usize> {
189 #[trusted]
190 #[logic(opaque)]
191 #[ensures(self.end_log()@ < seq.len() && self.start_log()@ <= self.end_log()@+1 ==> result)]
192 #[ensures(self.end_log()@ >= seq.len() ==> !result)]
193 fn in_bounds(self, seq: Seq<T>) -> bool {
194 dead
195 }
196
197 #[logic(open)]
198 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
199 pearlite! {
200 if self.is_empty_log() { out@ == Seq::empty() }
201 else { seq.subsequence(self.start_log()@, self.end_log()@ + 1) == out@ }
202 }
203 }
204
205 #[logic(open)]
206 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
207 pearlite! {
208 forall<i> 0 <= i
209 && (i < self.start_log()@ || self.end_log()@ < i || self.is_empty_log())
210 && i < old.len()
211 ==> old[i] == fin[i]
212 }
213 }
214}
215
216impl<T> SliceIndexSpec<[T]> for RangeTo<usize> {
217 #[logic(open)]
218 fn in_bounds(self, seq: Seq<T>) -> bool {
219 pearlite! { self.end@ <= seq.len() }
220 }
221
222 #[logic(open)]
223 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
224 pearlite! { seq.subsequence(0, self.end@) == out@ }
225 }
226
227 #[logic(open)]
228 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
229 pearlite! { forall<i> self.end@ <= i && i < old.len() ==> old[i] == fin[i] }
230 }
231}
232
233impl<T> SliceIndexSpec<[T]> for RangeFrom<usize> {
234 #[logic(open)]
235 fn in_bounds(self, seq: Seq<T>) -> bool {
236 pearlite! { self.start@ <= seq.len() }
237 }
238
239 #[logic(open)]
240 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
241 pearlite! { seq.subsequence(self.start@, seq.len()) == out@ }
242 }
243
244 #[logic(open)]
245 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
246 pearlite! {
247 forall<i> 0 <= i && i < self.start@ && i < old.len() ==> old[i] == fin[i]
248 }
249 }
250}
251
252impl<T> SliceIndexSpec<[T]> for RangeFull {
253 #[logic(open)]
254 fn in_bounds(self, _seq: Seq<T>) -> bool {
255 pearlite! { true }
256 }
257
258 #[logic(open)]
259 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
260 pearlite! { seq == out@ }
261 }
262
263 #[logic(open)]
264 fn resolve_elswhere(self, _old: Seq<T>, _fin: Seq<T>) -> bool {
265 pearlite! { true }
266 }
267}
268
269impl<T> SliceIndexSpec<[T]> for RangeToInclusive<usize> {
270 #[logic(open)]
271 fn in_bounds(self, seq: Seq<T>) -> bool {
272 pearlite! { self.end@ < seq.len() }
273 }
274
275 #[logic(open)]
276 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
277 pearlite! { seq.subsequence(0, self.end@ + 1) == out@ }
278 }
279
280 #[logic(open)]
281 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
282 pearlite! { forall<i> self.end@ < i && i < old.len() ==> old[i] == fin[i] }
283 }
284}
285
286#[logic(open, inline)]
287pub fn to_logic_range((lo, hi): (Bound<usize>, Bound<usize>), len: Int) -> Range<Int> {
288 pearlite! {
289 let lo = match lo {
290 Bound::Included(i) => i@,
291 Bound::Excluded(i) => i@ + 1,
292 Bound::Unbounded => 0
293 };
294 let hi = match hi {
295 Bound::Included(i) => i@ + 1,
296 Bound::Excluded(i) => i@,
297 Bound::Unbounded => len
298 };
299 lo..hi
300 }
301}
302
303impl<T> SliceIndexSpec<[T]> for (Bound<usize>, Bound<usize>) {
304 #[logic(open)]
305 fn in_bounds(self, seq: Seq<T>) -> bool {
306 let range = to_logic_range(self, seq.len());
307 pearlite! { range.start <= range.end && range.end <= seq.len() }
308 }
309
310 #[logic(open)]
311 fn has_value(self, seq: Seq<T>, out: [T]) -> bool {
312 let range = to_logic_range(self, seq.len());
313 pearlite! { seq.subsequence(range.start, range.end) == out@ }
314 }
315
316 #[logic(open)]
317 fn resolve_elswhere(self, old: Seq<T>, fin: Seq<T>) -> bool {
318 let range = to_logic_range(self, old.len());
319 pearlite! {
320 forall<i> 0 <= i && (i < range.start || range.end <= i) && i < old.len()
321 ==> old[i] == fin[i]
322 }
323 }
324}
325
326extern_spec! {
327 impl<T> [T] {
328 #[check(ghost)]
329 #[requires(self@.len() == src@.len())]
330 #[ensures((^self)@ == src@)]
331 fn copy_from_slice(&mut self, src: &[T]) where T: Copy;
332
333 #[check(ghost)]
334 #[ensures(self@.len() == result@)]
335 fn len(&self) -> usize;
336
337 #[check(ghost)]
338 #[requires(i@ < self@.len())]
339 #[requires(j@ < self@.len())]
340 #[ensures((^self)@.exchange(self@, i@, j@))]
341 fn swap(&mut self, i: usize, j: usize);
342
343 #[ensures(ix.in_bounds(self@) ==> exists<r> result == Some(r) && ix.has_value(self@, *r))]
344 #[ensures(ix.in_bounds(self@) || result == None)]
345 fn get<I: SliceIndexSpec<[T]>>(&self, ix: I) -> Option<&<I as SliceIndex<[T]>>::Output>;
346
347 #[ensures((^self)@.len() == self@.len())]
348 #[ensures(ix.in_bounds(self@) ==> exists<r>
349 result == Some(r) &&
350 ix.has_value(self@, *r) &&
351 ix.has_value((^self)@, ^r) &&
352 ix.resolve_elswhere(self@, (^self)@))]
353 #[ensures(ix.in_bounds(self@) || result == None)]
354 fn get_mut<I: SliceIndexSpec<[T]>>(&mut self, ix: I)
355 -> Option<&mut <I as SliceIndex<[T]>>::Output>;
356
357 #[check(ghost)]
358 #[requires(mid@ <= self@.len())]
359 #[ensures({
360 let (l,r) = result; let sl = self@.len();
361 ((^self)@.len() == sl) &&
362 self@.subsequence(0, mid@) == l@ &&
363 self@.subsequence(mid@, sl) == r@ &&
364 (^self)@.subsequence(0, mid@) == (^l)@ &&
365 (^self)@.subsequence(mid@, sl) == (^r)@
366 })]
367 fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]);
368
369 #[check(ghost)]
370 #[ensures(match result {
371 Some((first, tail)) => {
372 *first == self[0] && ^first == (^self)[0] &&
373 (*self)@.len() > 0 && (^self)@.len() > 0 &&
374 (*tail)@ == (*self)@.tail() &&
375 (^tail)@ == (^self)@.tail()
376 }
377 None => self@.len() == 0 && ^self == *self && self@ == Seq::empty()
378 })]
379 fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>;
380
381 #[check(ghost)]
382 #[ensures((^*self)@.len() == (**self)@.len())]
383 #[ensures((^^self)@.len() == (*^self)@.len())]
384 #[ensures(match result {
385 Some(r) => {
386 (**self)@.len() > 0 &&
387 r == &mut (**self)[0] &&
388 (^self).to_mut_seq() == (*self).to_mut_seq().tail()
389 }
390 None => resolve(self) && (^*self)@ == Seq::empty() && (**self)@ == Seq::empty()
391 })]
392 fn split_off_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>;
393
394 #[check(ghost)]
395 #[ensures((^*self)@.len() == (**self)@.len())]
396 #[ensures((^^self)@.len() == (*^self)@.len())]
397 #[ensures(match result {
398 Some(r) => {
399 (**self)@.len() > 0 &&
400 r == &mut (**self)[(**self)@.len()-1] &&
401 (^self).to_mut_seq() == (*self).to_mut_seq().subsequence(0, (*self).to_mut_seq().len()-1)
402 }
403 None => resolve(self) && (^*self)@ == Seq::empty() && (**self)@ == Seq::empty()
404 })]
405 fn split_off_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>;
406
407 #[check(ghost)]
408 #[ensures(result@ == self)]
409 fn iter(&self) -> Iter<'_, T>;
410
411 #[check(ghost)]
412 #[ensures(result@ == self)]
413 fn iter_mut(&mut self) -> IterMut<'_, T>;
414
415 #[check(ghost)]
416 #[ensures(result == None ==> self@.len() == 0)]
417 #[ensures(forall<x> result == Some(x) ==> self[self@.len() - 1] == *x)]
418 fn last(&self) -> Option<&T>;
419
420 #[check(ghost)]
421 #[ensures(result == None ==> self@.len() == 0)]
422 #[ensures(forall<x> result == Some(x) ==> self[0] == *x)]
423 fn first(&self) -> Option<&T>;
424
425
426 #[requires(self.deep_model().sorted())]
427 #[ensures(forall<i:usize> result == Ok(i) ==>
428 i@ < self@.len() && (*self).deep_model()[i@] == x.deep_model())]
429 #[ensures(forall<i:usize> result == Err(i) ==> i@ <= self@.len() &&
430 forall<j> 0 <= j && j < self@.len() ==> self.deep_model()[j] != x.deep_model())]
431 #[ensures(forall<i:usize> result == Err(i) ==>
432 forall<j:usize> j < i ==> self.deep_model()[j@] < x.deep_model())]
433 #[ensures(forall<i:usize> result == Err(i) ==>
434 forall<j:usize> i <= j && j@ < self@.len() ==> x.deep_model() < self.deep_model()[j@])]
435 fn binary_search(&self, x: &T) -> Result<usize, usize>
436 where T: Ord + DeepModel, T::DeepModelTy: OrdLogic,;
437
438 #[requires(ix.in_bounds(self@))]
439 #[ensures(ix.has_value(self@, *result))]
440 unsafe fn get_unchecked<I: SliceIndexSpec<[T]>>(&self, ix: I)
441 -> &<I as SliceIndex<[T]>>::Output;
442
443 #[requires(ix.in_bounds(self@))]
444 #[ensures(ix.has_value(self@, *result))]
445 #[ensures(ix.has_value((^self)@, ^result))]
446 #[ensures(ix.resolve_elswhere(self@, (^self)@))]
447 #[ensures((^self)@.len() == self@.len())]
448 unsafe fn get_unchecked_mut<I: SliceIndexSpec<[T]>>(&mut self, ix: I)
449 -> &mut <I as SliceIndex<[T]>>::Output;
450
451 #[check(ghost)]
453 fn as_ptr(&self) -> *const T;
454
455 #[check(ghost)]
457 fn as_mut_ptr(&mut self) -> *mut T;
458 }
459
460 impl<T, I: SliceIndexSpec<[T]>> IndexMut<I> for [T] {
461 #[check(ghost)]
462 #[requires(ix.in_bounds(self@))]
463 #[ensures(ix.has_value(self@, *result))]
464 #[ensures(ix.has_value((&^self)@, ^result))]
465 #[ensures(ix.resolve_elswhere(self@, (&^self)@))]
466 #[ensures((&^self)@.len() == self@.len())]
467 fn index_mut(&mut self, ix: I) -> &mut <[T] as Index<I>>::Output;
468 }
469
470 impl<T, I: SliceIndexSpec<[T]>> Index<I> for [T] {
471 #[check(ghost)]
472 #[requires(ix.in_bounds(self@))]
473 #[ensures(ix.has_value(self@, *result))]
474 fn index(&self, ix: I) -> &<[T] as Index<I>>::Output;
475 }
476
477 impl<'a, T> IntoIterator for &'a [T] {
478 #[check(ghost)]
479 #[ensures(self == result@)]
480 fn into_iter(self) -> Iter<'a, T>;
481 }
482
483 impl<'a, T> IntoIterator for &'a mut [T] {
484 #[check(ghost)]
485 #[ensures(self == result@)]
486 fn into_iter(self) -> IterMut<'a, T>;
487 }
488
489 impl<'a, T> Default for &'a mut [T] {
490 #[check(ghost)]
491 #[ensures((*result)@ == Seq::empty())]
492 #[ensures((^result)@ == Seq::empty())]
493 fn default() -> &'a mut [T];
494 }
495
496 impl<'a, T> Default for &'a [T] {
497 #[check(ghost)]
498 #[ensures(result@ == Seq::empty())]
499 fn default() -> &'a [T];
500 }
501
502 mod core {
503 mod slice {
504 #[check(ghost)]
505 #[ensures(result@.len() == 1)]
506 #[ensures(result@[0] == *s)]
507 fn from_ref<T>(s: &T) -> &[T];
508
509 #[check(ghost)]
510 #[ensures(result@.len() == 1)]
511 #[ensures(result@[0] == *s)]
512 #[ensures((^result)@.len() == 1)]
513 #[ensures((^result)@[0] == ^s)]
514 fn from_mut<T>(s: &mut T) -> &mut [T];
515 }
516 }
517}
518
519#[cfg(feature = "std")]
520extern_spec! {
521 impl<T> [T] {
522 #[check(ghost)]
523 #[ensures(result@ == self@)]
524 fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A>;
525
526 #[ensures(result@.len() == self@.len())]
528 #[ensures(forall<i> 0 <= i && i < self@.len() ==> <T as Clone>::clone.postcondition((&self@[i],), result@[i]))]
529 fn to_vec(&self) -> Vec<T> where T: Clone;
530 }
531
532 impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
533 #[ensures(forall<i> 0 <= i && i < self@.len() ==>
534 T::clone.postcondition((&self@[i],), result@[i]))]
535 fn clone(&self) -> Box<[T], A>;
536 }
537}
538
539impl<'a, T> View for Iter<'a, T> {
540 type ViewTy = &'a [T];
541
542 #[logic(opaque)]
543 fn view(self) -> Self::ViewTy {
544 dead
545 }
546}
547
548impl<'a, T> IteratorSpec for Iter<'a, T> {
549 #[logic(open, prophetic)]
550 fn completed(&mut self) -> bool {
551 pearlite! { resolve(self) && (*self@)@ == Seq::empty() }
552 }
553
554 #[logic(open)]
555 fn produces(self, visited: Seq<Self::Item>, tl: Self) -> bool {
556 pearlite! {
557 self@.to_ref_seq() == visited.concat(tl@.to_ref_seq())
558 }
559 }
560
561 #[logic(law)]
562 #[ensures(self.produces(Seq::empty(), self))]
563 fn produces_refl(self) {
564 let _ = Seq::<Self::Item>::concat_empty;
565 }
566
567 #[logic(law)]
568 #[requires(a.produces(ab, b))]
569 #[requires(b.produces(bc, c))]
570 #[ensures(a.produces(ab.concat(bc), c))]
571 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
572 let _ = Seq::<Self::Item>::concat_assoc;
573 }
574}
575
576extern_spec! {
577 impl<'a, T> Iterator for Iter<'a, T> {
578 #[ensures(result.0@ == self@@.len())]
579 #[ensures(result.1 == Some(result.0))]
580 fn size_hint(&self) -> (usize, Option<usize>);
581 }
582}
583
584impl<'a, T> ExactSizeIteratorSpec for Iter<'a, T> {
585 #[logic(law)]
586 #[requires(Self::size_hint.postcondition((self,), r))]
587 #[ensures(r.1 == Some(r.0))]
588 #[allow(unused_variables)]
589 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
590}
591
592impl<'a, T> DoubleEndedIteratorSpec for Iter<'a, T> {
593 #[logic(open)]
594 fn produces_back(self, visited: Seq<Self::Item>, o: Self) -> bool {
595 pearlite! {
596 self@.to_ref_seq() == o@.to_ref_seq().concat(visited.reverse())
597 }
598 }
599
600 #[logic(open, prophetic)]
601 fn completed_back(&mut self) -> bool {
602 self.completed()
603 }
604
605 #[logic(law)]
606 #[ensures(self.produces_back(Seq::empty(), self))]
607 fn produces_back_refl(self) {
608 let _ = Seq::<Self::Item>::reverse_empty();
609 let _ = Seq::<Self::Item>::concat_empty;
610 }
611
612 #[logic(law)]
613 #[requires(a.produces_back(ab, b))]
614 #[requires(b.produces_back(bc, c))]
615 #[ensures(a.produces_back(ab.concat(bc), c))]
616 fn produces_back_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
617 let _ = ab.reverse_concat(bc);
618 let _ = Seq::<Self::Item>::concat_assoc;
619 }
620
621 #[logic(law)]
622 #[requires(Self::size_hint.postcondition((self,), r))]
623 #[ensures(forall<s: Seq<Self::Item>, i: &mut Self>
624 self.produces_back(s, *i) && i.completed_back() ==> r.0@ <= s.len())]
625 #[ensures(match r.1 {
626 Some(r) => {
627 forall<s: Seq<Self::Item>, i: Self> self.produces_back(s, i) ==> s.len() <= r@
628 }
629 None => true
630 })]
631 fn size_hint_back_spec(&self, r: (usize, Option<usize>)) {}
632}
633
634impl<'a, T> View for IterMut<'a, T> {
635 type ViewTy = &'a mut [T];
636
637 #[trusted]
638 #[logic(opaque)]
639 #[ensures((^result)@.len() == (*result)@.len())]
640 fn view(self) -> Self::ViewTy {
641 dead
642 }
643}
644
645impl<'a, T> Resolve for IterMut<'a, T> {
646 #[logic(open, prophetic, inline)]
647 fn resolve(self) -> bool {
648 pearlite! { *self@ == ^self@ }
649 }
650
651 #[trusted]
652 #[logic(prophetic)]
653 #[requires(structural_resolve(self))]
654 #[ensures(self.resolve())]
655 fn resolve_coherence(self) {}
656}
657
658impl<'a, T> IteratorSpec for IterMut<'a, T> {
659 #[logic(open, prophetic)]
660 fn completed(&mut self) -> bool {
661 pearlite! { resolve(self) && (*self@)@ == Seq::empty() }
662 }
663
664 #[logic(open)]
665 fn produces(self, visited: Seq<Self::Item>, tl: Self) -> bool {
666 pearlite! {
667 self@.to_mut_seq() == visited.concat(tl@.to_mut_seq())
668 }
669 }
670
671 #[logic(law)]
672 #[ensures(self.produces(Seq::empty(), self))]
673 fn produces_refl(self) {
674 let _ = Seq::<Self::Item>::concat_empty;
675 }
676
677 #[logic(law)]
678 #[requires(a.produces(ab, b))]
679 #[requires(b.produces(bc, c))]
680 #[ensures(a.produces(ab.concat(bc), c))]
681 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
682 let _ = Seq::<Self::Item>::concat_assoc;
683 }
684}
685
686extern_spec! {
687 impl<'a, T> Iterator for IterMut<'a, T> {
688 #[ensures(result.0@ == self@@.len())]
689 #[ensures(result.1 == Some(result.0))]
690 fn size_hint(&self) -> (usize, Option<usize>);
691 }
692}
693
694impl<'a, T> ExactSizeIteratorSpec for IterMut<'a, T> {
695 #[logic(law)]
696 #[requires(Self::size_hint.postcondition((self,), r))]
697 #[ensures(r.1 == Some(r.0))]
698 #[allow(unused_variables)]
699 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
700}
701
702impl<'a, T> DoubleEndedIteratorSpec for IterMut<'a, T> {
703 #[logic(open)]
704 fn produces_back(self, visited: Seq<Self::Item>, o: Self) -> bool {
705 pearlite! {
706 self@.to_mut_seq() == o@.to_mut_seq().concat(visited.reverse())
707 }
708 }
709
710 #[logic(open, prophetic)]
711 fn completed_back(&mut self) -> bool {
712 self.completed()
713 }
714
715 #[logic(law)]
716 #[ensures(self.produces_back(Seq::empty(), self))]
717 fn produces_back_refl(self) {
718 let _ = Seq::<Self::Item>::reverse_empty();
719 let _ = Seq::<Self::Item>::concat_empty;
720 }
721
722 #[logic(law)]
723 #[requires(a.produces_back(ab, b))]
724 #[requires(b.produces_back(bc, c))]
725 #[ensures(a.produces_back(ab.concat(bc), c))]
726 fn produces_back_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
727 let _ = ab.reverse_concat(bc);
728 let _ = Seq::<Self::Item>::concat_assoc;
729 }
730
731 #[logic(law)]
732 #[requires(Self::size_hint.postcondition((self,), r))]
733 #[ensures(forall<s: Seq<Self::Item>, i: &mut Self>
734 self.produces_back(s, *i) && i.completed_back() ==> r.0@ <= s.len())]
735 #[ensures(match r.1 {
736 Some(r) => {
737 forall<s: Seq<Self::Item>, i: Self> self.produces_back(s, i) ==> s.len() <= r@
738 }
739 None => true
740 })]
741 fn size_hint_back_spec(&self, r: (usize, Option<usize>)) {}
742}
743
744extern_spec! {
745 impl<'a, T> Iter<'a, T> {
746 #[ensures(result@ == self@@)]
747 fn as_slice(&self) -> &'a [T];
748 }
749
750 impl<'a, T> ExactSizeIterator for Iter<'a, T> {
751 #[ensures(result@ == self@@.len())]
752 fn len(&self) -> usize;
753 }
754
755 impl<'a, T> IterMut<'a, T> {
756 #[ensures(result@ == self@@)]
757 fn as_slice(&self) -> &'a [T];
758 }
759
760 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {
761 #[ensures(result@ == self@@.len())]
762 fn len(&self) -> usize;
763 }
764}