1use crate::{ghost::Plain, logic::ops::Fin, prelude::*};
4
5#[cfg(creusot)]
6use crate::ghost::Objective;
7use core::marker::PhantomData;
8#[cfg(creusot)]
9use core::ops::{Deref, DerefMut};
10
11#[intrinsic("snapshot")]
32pub struct Snapshot<T: ?Sized>(PhantomData<T>);
33
34#[cfg(creusot)]
35impl<T: ?Sized> Deref for Snapshot<T> {
36 type Target = T;
37
38 #[logic]
39 #[builtin("identity")]
40 #[intrinsic("snapshot_deref")]
41 fn deref(&self) -> &Self::Target {
42 dead
43 }
44}
45
46#[cfg(creusot)]
47impl<T: ?Sized> DerefMut for Snapshot<T> {
48 #[logic]
49 #[builtin("identity")]
50 #[intrinsic("snapshot_deref_mut")]
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 dead
53 }
54}
55
56impl<T: ?Sized + Fin> Fin for Snapshot<T> {
57 type Target = T::Target;
58
59 #[logic(open, prophetic, inline)]
60 fn fin<'a>(self) -> &'a Self::Target {
61 pearlite! { &^*self }
62 }
63}
64
65impl<T: ?Sized> Clone for Snapshot<T> {
66 #[check(ghost)]
67 #[ensures(result == *self)]
68 fn clone(&self) -> Self {
69 *self
70 }
71}
72
73impl<T: ?Sized> Copy for Snapshot<T> {}
74
75#[cfg(creusot)]
76#[trusted]
77impl<T> Objective for Snapshot<T> {}
78
79impl<T: ?Sized> Snapshot<T> {
80 #[logic]
82 #[builtin("identity")]
83 pub fn new(value: T) -> Snapshot<T> {
84 let _ = value;
85 dead
86 }
87}
88
89impl<T> Snapshot<T> {
90 #[logic]
102 #[builtin("identity")]
103 pub fn inner(self) -> T {
104 dead
105 }
106
107 #[doc(hidden)]
109 #[cfg(not(creusot))]
110 pub fn from_fn(_: fn() -> T) -> Self {
111 Snapshot(PhantomData)
112 }
113
114 #[requires(inv(*self))]
116 #[ensures(*result == *self)]
117 #[check(ghost)]
118 pub fn into_ghost(self) -> Ghost<T>
119 where
120 T: Plain,
121 {
122 T::into_ghost(self)
123 }
124}