1#[cfg(creusot)]
2use crate::logic::{Mapping, any};
3use crate::{
4 ghost::Plain, logic::ord::ord_laws_impl, prelude::*, std::iter::ExactSizeIteratorSpec,
5};
6use core::option::*;
7#[cfg(creusot)]
8use core::{cmp::Ordering, marker::Destruct};
9
10impl<T: DeepModel> DeepModel for Option<T> {
11 type DeepModelTy = Option<T::DeepModelTy>;
12
13 #[logic(open, inline)]
14 fn deep_model(self) -> Self::DeepModelTy {
15 match self {
16 Some(t) => Some(t.deep_model()),
17 None => None,
18 }
19 }
20}
21
22extern_spec! {
23 impl<T: PartialEq + DeepModel> PartialEq for Option<T> {
24 #[allow(unstable_name_collisions)]
25 #[ensures(result == (self.deep_model() == rhs.deep_model()))]
26 fn eq(&self, rhs: &Self) -> bool {
27 match (self, rhs) {
28 (None, None) => true,
29 (Some(x), Some(y)) => x == y,
30 _ => false,
31 }
32 }
33 }
34
35 impl<T: Clone> Clone for Option<T> {
36 #[ensures(match (*self, result) {
37 (None, None) => true,
38 (Some(s), Some(r)) => T::clone.postcondition((&s,), r),
39 _ => false
40 })]
41 fn clone(&self) -> Option<T> {
42 match self {
43 None => None,
44 Some(x) => Some(x.clone())
45 }
46 }
47 }
48
49 impl<T> Option<T> {
50 #[check(ghost)]
51 #[erasure]
52 #[ensures(result == (*self != None))]
53 fn is_some(&self) -> bool {
54 match *self {
55 Some(_) => true,
56 None => false,
57 }
58 }
59
60 #[erasure]
61 #[requires(match self { None => true, Some(t) => f.precondition((t,)) })]
62 #[ensures(match self {
63 None => resolve(f) && result == false,
64 Some(t) => f.postcondition_once((t,), result),
65 })]
66 fn is_some_and(self, f: impl FnOnce(T) -> bool + Destruct) -> bool {
67 match self {
68 None => false,
69 Some(t) => f(t),
70 }
71 }
72
73 #[check(ghost)]
74 #[erasure]
75 #[ensures(result == (*self == None))]
76 fn is_none(&self) -> bool {
77 !self.is_some()
78 }
79
80 #[check(ghost)]
81 #[erasure]
82 #[ensures(*self == None ==> result == None)]
83 #[ensures(
84 *self == None || exists<r: &T> result == Some(r) && *self == Some(*r)
85 )]
86 fn as_ref(&self) -> Option<&T> {
87 match *self {
88 Some(ref t) => Some(t),
89 None => None,
90 }
91 }
92
93 #[check(ghost)]
94 #[erasure]
95 #[ensures(*self == None ==> result == None && ^self == None)]
96 #[ensures(
97 *self == None
98 || exists<r: &mut T> result == Some(r) && *self == Some(*r) && ^self == Some(^r)
99 )]
100 fn as_mut(&mut self) -> Option<&mut T> {
101 match *self {
102 Some(ref mut t) => Some(t),
103 None => None,
104 }
105 }
106
107 #[check(ghost)]
112 #[ensures(match *self {
113 None => result@.len() == 0,
114 Some(t) => result@.len() == 1 && result@[0] == t
115 })]
116 fn as_slice(&self) -> &[T] {
117 match self {
118 None => &[],
119 Some(t) => core::slice::from_ref(t),
120 }
121 }
122
123 #[check(ghost)]
124 #[ensures(match *self {
125 None => result@.len() == 0,
126 Some(_) => exists<b:&mut T>
127 *self == Some(*b) && ^self == Some(^b) &&
128 (*result)@[0] == *b && (^result)@[0] == ^b &&
129 (*result)@.len() == 1 && (^result)@.len() == 1,
130 })]
131 fn as_mut_slice(&mut self) -> &mut [T] {
132 match self {
133 None => &mut [],
134 Some(t) => core::slice::from_mut(t),
135 }
136 }
137
138 #[check(ghost)]
139 #[requires(self != None)]
140 #[ensures(Some(result) == self)]
141 fn expect(self, msg: &str) -> T {
142 match self {
143 None => panic!(),
144 Some(t) => t,
145 }
146 }
147
148 #[check(ghost)]
149 #[requires(self != None)]
150 #[ensures(Some(result) == self)]
151 fn unwrap(self) -> T {
152 match self {
153 None => panic!(),
154 Some(t) => t,
155 }
156 }
157
158 #[check(ghost)]
159 #[erasure]
160 #[ensures(self == None ==> result == default)]
161 #[ensures(self == None || (self == Some(result) && resolve(default)))]
162 fn unwrap_or(self, default: T) -> T {
163 match self {
164 Some(t) => t,
165 None => default,
166 }
167 }
168
169 #[erasure]
170 #[requires(self == None ==> f.precondition(()))]
171 #[ensures(match self {
172 None => f.postcondition_once((), result),
173 Some(t) => resolve(f) && result == t
174 })]
175 fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
176 match self {
177 Some(t) => t,
178 None => f(),
179 }
180 }
181
182 #[erasure]
183 #[ensures(self == None ==> T::default.postcondition((), result))]
184 #[ensures(self == None || self == Some(result))]
185 fn unwrap_or_default(self) -> T
186 where
187 T: Default {
188 match self {
189 Some(t) => t,
190 None => T::default(),
191 }
192 }
193
194 #[check(ghost)]
195 #[requires(self != None)]
196 #[ensures(Some(result) == self)]
197 unsafe fn unwrap_unchecked(self) -> T {
198 match self {
199 None => panic!(),
200 Some(t) => t,
201 }
202 }
203
204 #[erasure]
205 #[requires(match self { None => true, Some(t) => f.precondition((t,)) })]
206 #[ensures(match self {
207 None => resolve(f) && result == None,
208 Some(t) => exists<r> result == Some(r) && f.postcondition_once((t,), r),
209 })]
210 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
211 match self {
212 Some(t) => Some(f(t)),
213 None => None,
214 }
215 }
216
217 #[requires(match self { None => true, Some(t) => f.precondition((&t,)) })]
218 #[ensures(result == self)]
219 #[ensures(match self {
220 None => resolve(f),
221 Some(t) => f.postcondition_once((&t,), ()),
222 })]
223 fn inspect<F: FnOnce(&T)>(self, f: F) -> Option<T> {
224 match self {
225 None => None,
226 Some(t) => { f(&t); Some(t) }
227 }
228 }
229
230 #[requires(match self { None => true, Some(t) => f.precondition((t,)) })]
231 #[ensures(match self {
232 None => resolve(f) && result == default,
233 Some(t) => f.postcondition_once((t,), result)
234 })]
235 fn map_or<U, F: FnOnce(T) -> U>(self, default: U, f: F) -> U {
236 match self {
237 None => default,
238 Some(t) => f(t),
239 }
240 }
241
242 #[requires(match self {
243 None => default.precondition(()),
244 Some(t) => f.precondition((t,)),
245 })]
246 #[ensures(match self {
247 None => resolve(f) && default.postcondition_once((), result),
248 Some(t) => resolve(default) && f.postcondition_once((t,), result),
249 })]
250 fn map_or_else<U, D: FnOnce() -> U, F: FnOnce(T) -> U>(self, default: D, f: F) -> U {
251 match self {
252 None => default(),
253 Some(t) => f(t),
254 }
255 }
256
257 #[check(ghost)]
258 #[ensures(match self {
259 None => result == Err(err),
260 Some(t) => result == Ok(t) && resolve(err),
261 })]
262 fn ok_or<E>(self, err: E) -> Result<T, E> {
263 match self {
264 None => Err(err),
265 Some(t) => Ok(t),
266 }
267 }
268
269 #[requires(self == None ==> err.precondition(()))]
270 #[ensures(match self {
271 None => exists<r> result == Err(r) && err.postcondition_once((), r),
272 Some(t) => resolve(err) && result == Ok(t),
273 })]
274 fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
275 match self {
276 None => Err(err()),
277 Some(t) => Ok(t),
278 }
279 }
280
281 #[requires(match self {
282 None => true,
283 Some(x) => T::deref.precondition((x,)),
284 })]
285 #[ensures(match (self, result) {
286 (None, None) => true,
287 (Some(x), Some(r)) => T::deref.postcondition((x,), r),
288 _ => false,
289 })]
290 fn as_deref(&self) -> Option<&<T as ::core::ops::Deref>::Target>
291 where T: ::core::ops::Deref,
292 {
293 match self {
294 Some(x) => Some(&*x),
295 None => None,
296 }
297 }
298
299 #[requires(match *self {
300 None => true,
301 Some(cur) => forall<bor: &mut T> *bor == cur ==> T::deref_mut.precondition((bor,)),
302 })]
303 #[ensures(match (*self, ^self, result) {
304 (None, None, None) => true,
305 (Some(cur), Some(fin), Some(r)) => exists<bor: &mut T> *bor == cur && ^bor == fin && T::deref_mut.postcondition((bor,), r),
306 _ => false,
307 })]
308 fn as_deref_mut(&mut self) -> Option<&mut<T as ::core::ops::Deref>::Target>
309 where T: ::core::ops::DerefMut,
310 {
311 match self {
312 Some(x) => Some(&mut *x),
313 None => None,
314 }
315 }
316
317 #[ensures(match *self {
318 None => exists<it: &mut Iter<'_, T>> it.completed() && *it == result,
319 Some(x) => exists<s: Seq<&T>, it: &mut Iter<'_, T>> {
320 it.completed() && s.len() == 1 && *s[0] == x && result.produces(s, *it)
321 }
322 })]
323 fn iter(&self) -> Iter<'_, T>;
324
325 #[ensures(match (*self, ^self) {
326 (None, None) => exists<it: &mut IterMut<'_, T>> it.completed() && *it == result,
327 (Some(cur), Some(fin)) => exists<s: Seq<&mut T>, it: &mut IterMut<'_, T>> {
328 it.completed() && s.len() == 1 && *s[0] == cur && ^s[0] == fin && result.produces(s, *it)
329 },
330 _ => false,
331 })]
332 fn iter_mut(&mut self) -> IterMut<'_, T>;
333
334
335 #[check(ghost)]
336 #[ensures(self == None ==> result == None && resolve(optb))]
337 #[ensures(self == None || (result == optb && resolve(self)))]
338 fn and<U>(self, optb: Option<U>) -> Option<U> {
339 match self {
340 None => None,
341 Some(_) => optb,
342 }
343 }
344
345 #[requires(match self { None => true, Some(t) => f.precondition((t,)) })]
346 #[ensures(match self {
347 None => resolve(f) &&result == None,
348 Some(t) => f.postcondition_once((t,), result),
349 })]
350 fn and_then<U, F: FnOnce(T) -> Option<U>>(self, f: F) -> Option<U> {
351 match self {
352 None => None,
353 Some(t) => f(t),
354 }
355 }
356
357 #[requires(match self { None => true, Some(t) => predicate.precondition((&t,)) })]
358 #[ensures(match self {
359 None => resolve(predicate) && result == None,
360 Some(t) => match result {
361 None => predicate.postcondition_once((&t,), false) && resolve(t),
362 Some(r) => predicate.postcondition_once((&t,), true) && r == t,
363 },
364 })]
365 fn filter<P: FnOnce(&T) -> bool>(self, predicate: P) -> Option<T> {
366 match self {
367 None => None,
368 Some(t) => if predicate(&t) { Some(t) } else { None }
369 }
370 }
371
372 #[check(ghost)]
373 #[ensures(self == None ==> result == optb)]
374 #[ensures(self == None || (result == self && resolve(optb)))]
375 fn or(self, optb: Option<T>) -> Option<T> {
376 match self {
377 None => optb,
378 Some(t) => Some(t),
379 }
380 }
381
382 #[requires(self == None ==> f.precondition(()))]
383 #[ensures(match self {
384 None => f.postcondition_once((), result),
385 Some(t) => resolve(f) && result == Some(t),
386 })]
387 fn or_else<F: FnOnce() -> Option<T>>(self, f: F) -> Option<T> {
388 match self {
389 None => f(),
390 Some(t) => Some(t),
391 }
392 }
393
394 #[check(ghost)]
395 #[ensures(match (self, optb) {
396 (None, None) => result == None,
397 (Some(t1), Some(t2)) => result == None && resolve(t1) && resolve(t2),
398 (Some(t), None) => result == Some(t),
399 (None, Some(t)) => result == Some(t),
400 })]
401 fn xor(self, optb: Option<T>) -> Option<T> {
402 match (self, optb) {
403 (Some(t), None) | (None, Some(t)) => Some(t),
404 _ => None,
405 }
406 }
407
408 #[check(ghost)]
409 #[ensures(match *self { Some(t) => resolve(t), None => true })]
410 #[ensures(*result == value && ^self == Some(^result))]
411 fn insert(&mut self, value: T) -> &mut T {
412 *self = Some(value);
413 match self {
414 None => unreachable!(),
415 Some(v) => v,
416 }
417 }
418
419 #[check(ghost)]
420 #[ensures(match *self {
421 None => *result == value && ^self == Some(^result),
422 Some(_) => *self == Some(*result) && ^self == Some(^result) && resolve(value),
423 })]
424 fn get_or_insert(&mut self, value: T) -> &mut T {
425 match self {
426 None => *self = Some(value),
427 Some(_) => {}
428 }
429 match self {
430 None => unreachable!(),
431 Some(v) => v,
432 }
433 }
434
435 #[requires(match self {
436 None => T::default.precondition(()),
437 Some(_) => true,
438 })]
439 #[ensures(match *self {
440 None => T::default.postcondition((), *result) && ^self == Some(^result),
441 Some(_) => *self == Some(*result) && ^self == Some(^result),
442 })]
443 fn get_or_insert_default(&mut self) -> &mut T
444 where T: Default,
445 {
446 self.get_or_insert(T::default())
447 }
448
449 #[requires(*self == None ==> f.precondition(()))]
450 #[ensures(match *self {
451 None => f.postcondition_once((), *result) && ^self == Some(^result),
452 Some(_) => *self == Some(*result) && ^self == Some(^result),
453 })]
454 fn get_or_insert_with<F: FnOnce() -> T>(&mut self, f: F) -> &mut T {
455 match self {
456 None => { *self = Some(f()); self.as_mut().unwrap() }
457 Some(t) => t,
458 }
459 }
460
461 #[check(ghost)]
462 #[ensures(result == *self && ^self == None)]
463 fn take(&mut self) -> Option<T> {
464 core::mem::replace(self, None)
465 }
466
467 #[requires(match *self {
468 None => true,
469 Some(t) => forall<b:&mut T> inv(b) && *b == t ==> predicate.precondition((b,)),
470 })]
471 #[ensures(match *self {
472 None => result == None && ^self == None,
473 Some(cur) =>
474 exists<b: &mut T, res: bool> inv(b) && cur == *b && predicate.postcondition_once((b,), res) &&
475 if res {
476 ^self == None && result == Some(^b)
477 } else {
478 ^self == Some(^b) && result == None
479 }
480 })]
481 fn take_if<P: FnOnce(&mut T) -> bool>(&mut self, predicate: P) -> Option<T> {
482 match self {
483 None => None,
484 Some(t) => if predicate(t) { self.take() } else { None },
485 }
486 }
487
488 #[check(ghost)]
489 #[ensures(result == *self && ^self == Some(value))]
490 fn replace(&mut self, value: T) -> Option<T> {
491 core::mem::replace(self, Some(value))
492 }
493
494 #[check(ghost)]
495 #[ensures(match (self, other) {
496 (None, _) => result == None && resolve(other),
497 (_, None) => result == None && resolve(self),
498 (Some(t), Some(u)) => result == Some((t, u)),
499 })]
500 fn zip<U>(self, other: Option<U>) -> Option<(T, U)> {
501 match (self, other) {
502 (Some(t), Some(u)) => Some((t, u)),
503 _ => None,
504 }
505 }
506 }
507
508 impl<T, U> Option<(T, U)> {
509 #[check(ghost)]
510 #[ensures(match self {
511 None => result == (None, None),
512 Some((t, u)) => result == (Some(t), Some(u)),
513 })]
514 fn unzip(self) -> (Option<T>, Option<U>) {
515 match self {
516 Some((t, u)) => (Some(t), Some(u)),
517 None => (None, None),
518 }
519 }
520 }
521
522 impl<T> Option<&T> {
523 #[check(ghost)]
524 #[ensures(match self {
525 None => result == None,
526 Some(s) => result == Some(*s)
527 })]
528 fn copied(self) -> Option<T>
529 where
530 T: Copy
531 {
532 match self {
533 None => None,
534 Some(t) => Some(*t),
535 }
536 }
537
538 #[ensures(match (self, result) {
539 (None, None) => true,
540 (Some(s), Some(r)) =>T::clone.postcondition((s,), r),
541 _ => false
542 })]
543 fn cloned(self) -> Option<T>
544 where
545 T: Clone
546 {
547 match self {
548 None => None,
549 Some(t) => Some(t.clone()),
550 }
551 }
552 }
553
554 impl<T> Option<&mut T> {
555 #[check(ghost)]
556 #[ensures(match self {
557 None => result == None,
558 Some(s) => result == Some(*s) && ^s == *s
559 })]
560 fn copied(self) -> Option<T>
561 where
562 T: Copy
563 {
564 match self {
565 None => None,
566 Some(t) => Some(*t),
567 }
568 }
569
570 #[ensures(match (self, result) {
571 (None, None) => true,
572 (Some(s), Some(r)) => T::clone.postcondition((s,), r) && ^s == *s,
573 _ => false
574 })]
575 fn cloned(self) -> Option<T>
576 where
577 T: Clone
578 {
579 match self {
580 None => None,
581 Some(t) => Some(t.clone()),
582 }
583 }
584 }
585
586 impl<T, E> Option<Result<T, E>> {
587 #[check(ghost)]
588 #[ensures(match self {
589 None => result == Ok(None),
590 Some(Ok(ok)) => result == Ok(Some(ok)),
591 Some(Err(err)) => result == Err(err),
592 })]
593 fn transpose(self) -> Result<Option<T>, E> {
594 match self {
595 None => Ok(None),
596 Some(Ok(ok)) => Ok(Some(ok)),
597 Some(Err(err)) => Err(err),
598 }
599 }
600 }
601
602 impl<T> Option<Option<T>> {
603 #[check(ghost)]
604 #[ensures(self == None ==> result == None)]
605 #[ensures(self == None || self == Some(result))]
606 fn flatten(self) -> Option<T> {
607 match self {
608 None => None,
609 Some(opt) => opt,
610 }
611 }
612 }
613
614 impl<T> IntoIterator for Option<T>{
615 #[check(ghost)]
616 #[ensures(self == result@)]
617 fn into_iter(self) -> IntoIter<T>;
618 }
619
620 impl<'a, T> IntoIterator for &'a Option<T>{
621 #[check(ghost)]
622 #[ensures(*self == match result@ { None => None, Some(r) => Some(*r) })]
623 fn into_iter(self) -> Iter<'a, T>;
624 }
625
626 impl<'a, T> IntoIterator for &'a mut Option<T>{
627 #[check(ghost)]
628 #[ensures(*self == match result@ { None => None, Some(r) => Some(*r) })]
629 #[ensures(^self == match result@ { None => None, Some(r) => Some(^r) })]
630 fn into_iter(self) -> IterMut<'a, T>;
631 }
632
633 impl<T> Default for Option<T> {
634 #[check(ghost)]
635 #[ensures(result == None)]
636 fn default() -> Option<T>;
637 }
638}
639
640impl<T: OrdLogic> OrdLogic for Option<T> {
641 #[logic(open)]
642 fn cmp_log(self, o: Self) -> Ordering {
643 match (self, o) {
644 (None, None) => Ordering::Equal,
645 (None, Some(_)) => Ordering::Less,
646 (Some(_), None) => Ordering::Greater,
647 (Some(x), Some(y)) => x.cmp_log(y),
648 }
649 }
650
651 ord_laws_impl! {}
652}
653
654impl<T> View for IntoIter<T> {
655 type ViewTy = Option<T>;
656
657 #[logic(opaque)]
658 fn view(self) -> Option<T> {
659 dead
660 }
661}
662
663impl<T> IteratorSpec for IntoIter<T> {
664 #[logic(open, prophetic)]
665 fn completed(&mut self) -> bool {
666 pearlite! { (*self)@ == None && resolve(self) }
667 }
668
669 #[logic(open)]
670 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
671 pearlite! {
672 visited == Seq::empty() && self == o ||
673 exists<e: Self::Item> self@ == Some(e) && visited == Seq::singleton(e) && o@ == None
674 }
675 }
676
677 #[logic(law)]
678 #[ensures(self.produces(Seq::empty(), self))]
679 fn produces_refl(self) {}
680
681 #[logic(law)]
682 #[requires(a.produces(ab, b))]
683 #[requires(b.produces(bc, c))]
684 #[ensures(a.produces(ab.concat(bc), c))]
685 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
686 let _ = Seq::<T>::concat_empty;
687 }
688}
689
690extern_spec! {
691 impl<T> Iterator for IntoIter<T> {
692 #[ensures(result.0 == match self@ { Some(_) => 1usize, None => 0usize })]
693 #[ensures(result.1 == Some(result.0))]
694 fn size_hint(&self) -> (usize, Option<usize>);
695 }
696}
697
698impl<T> ExactSizeIteratorSpec for IntoIter<T> {
699 #[logic(law)]
700 #[requires(Self::size_hint.postcondition((self,), r))]
701 #[ensures(r.1 == Some(r.0))]
702 #[allow(unused_variables)]
703 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
704}
705
706impl<'a, T> View for Iter<'a, T> {
707 type ViewTy = Option<&'a T>;
708
709 #[logic(opaque)]
710 fn view(self) -> Option<&'a T> {
711 dead
712 }
713}
714
715impl<T> IteratorSpec for Iter<'_, T> {
716 #[logic(open, prophetic)]
717 fn completed(&mut self) -> bool {
718 pearlite! { (*self)@ == None && resolve(self) }
719 }
720
721 #[logic(open)]
722 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
723 pearlite! {
724 visited == Seq::empty() && self == o ||
725 exists<e: Self::Item> self@ == Some(e) && visited == Seq::singleton(e) && o@ == None
726 }
727 }
728
729 #[logic(law)]
730 #[ensures(self.produces(Seq::empty(), self))]
731 fn produces_refl(self) {}
732
733 #[logic(law)]
734 #[requires(a.produces(ab, b))]
735 #[requires(b.produces(bc, c))]
736 #[ensures(a.produces(ab.concat(bc), c))]
737 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
738 let _ = Seq::<T>::concat_empty;
739 }
740}
741
742extern_spec! {
743 impl<T> Iterator for Iter<'_, T> {
744 #[ensures(result.0 == match self@ { Some(_) => 1usize, None => 0usize })]
745 #[ensures(result.1 == Some(result.0))]
746 fn size_hint(&self) -> (usize, Option<usize>);
747 }
748}
749
750impl<T> ExactSizeIteratorSpec for Iter<'_, T> {
751 #[logic(law)]
752 #[requires(Self::size_hint.postcondition((self,), r))]
753 #[ensures(r.1 == Some(r.0))]
754 #[allow(unused_variables)]
755 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
756}
757
758impl<'a, T> View for IterMut<'a, T> {
759 type ViewTy = Option<&'a mut T>;
760
761 #[logic(opaque)]
762 fn view(self) -> Option<&'a mut T> {
763 dead
764 }
765}
766
767impl<T: Plain> Plain for Option<T> {
768 #[ensures(*result == *snap)]
769 #[check(ghost)]
770 #[allow(unused_variables)]
771 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
772 ghost! {
773 let c: Snapshot<bool> = snapshot!(*snap == None);
774 if *c.into_ghost() {
775 None
776 } else {
777 let t: Snapshot<T> = snapshot!(snap.unwrap_logic());
778 Some(*t.into_ghost())
779 }
780 }
781 }
782}
783
784impl<T> IteratorSpec for IterMut<'_, T> {
785 #[logic(open, prophetic)]
786 fn completed(&mut self) -> bool {
787 pearlite! { (*self)@ == None && resolve(self) }
788 }
789
790 #[logic(open)]
791 fn produces(self, visited: Seq<Self::Item>, o: Self) -> bool {
792 pearlite! {
793 visited == Seq::empty() && self == o ||
794 exists<e: Self::Item> self@ == Some(e) && visited == Seq::singleton(e) && o@ == None
795 }
796 }
797
798 #[logic(law)]
799 #[ensures(self.produces(Seq::empty(), self))]
800 fn produces_refl(self) {}
801
802 #[logic(law)]
803 #[requires(a.produces(ab, b))]
804 #[requires(b.produces(bc, c))]
805 #[ensures(a.produces(ab.concat(bc), c))]
806 fn produces_trans(a: Self, ab: Seq<Self::Item>, b: Self, bc: Seq<Self::Item>, c: Self) {
807 let _ = Seq::<T>::concat_empty;
808 }
809}
810
811extern_spec! {
812 impl<T> Iterator for IterMut<'_, T> {
813 #[ensures(result.0 == match self@ { Some(_) => 1usize, None => 0usize })]
814 #[ensures(result.1 == Some(result.0))]
815 fn size_hint(&self) -> (usize, Option<usize>);
816 }
817}
818
819impl<T> ExactSizeIteratorSpec for IterMut<'_, T> {
820 #[logic(law)]
821 #[requires(Self::size_hint.postcondition((self,), r))]
822 #[ensures(r.1 == Some(r.0))]
823 #[allow(unused_variables)]
824 fn size_hint_exact(&self, r: (usize, Option<usize>)) {}
825}
826
827pub trait OptionExt<T> {
828 #[logic]
830 #[requires(false)]
831 fn unwrap_logic(self) -> T;
832
833 #[logic]
835 fn and_then_logic<U>(self, f: Mapping<T, Option<U>>) -> Option<U>;
836
837 #[logic]
839 fn map_logic<U>(self, f: Mapping<T, U>) -> Option<U>;
840}
841
842impl<T> OptionExt<T> for Option<T> {
843 #[logic(open)]
844 #[requires(self != None)]
845 fn unwrap_logic(self) -> T {
846 match self {
847 Some(x) => x,
848 None => any(),
849 }
850 }
851
852 #[logic(open)]
853 fn and_then_logic<U>(self, f: Mapping<T, Option<U>>) -> Option<U> {
854 match self {
855 None => None,
856 Some(x) => f.get(x),
857 }
858 }
859
860 #[logic(open)]
861 fn map_logic<U>(self, f: Mapping<T, U>) -> Option<U> {
862 match self {
863 None => None,
864 Some(x) => Some(f.get(x)),
865 }
866 }
867}