1use crate::{ghost::Plain, logic::ops::Fin, prelude::*};
4
5#[cfg(creusot)]
6use crate::ghost::Objective;
7#[cfg(creusot)]
8use crate::logic::ops::{DerefLogic, DerefMutLogic};
9use core::marker::PhantomData;
10#[cfg(creusot)]
11use core::ops::{Deref, DerefMut};
12
13#[intrinsic("snapshot")]
34pub struct Snapshot<T: ?Sized>(PhantomData<T>);
35
36#[cfg(creusot)]
37impl<T: ?Sized> Deref for Snapshot<T> {
38 type Target = T;
39
40 #[check(ghost)]
41 #[requires(false)]
42 #[logic_alias(self.deref_logic())]
43 fn deref(&self) -> &Self::Target {
44 panic!("Snapshot values cannot be dereferenced in program")
45 }
46}
47
48#[cfg(creusot)]
49impl<T: ?Sized> DerefMut for Snapshot<T> {
50 #[check(ghost)]
51 #[requires(false)]
52 #[logic_alias(self.deref_mut_logic())]
53 fn deref_mut(&mut self) -> &mut Self::Target {
54 panic!("Snapshot values cannot be dereferenced in program")
55 }
56}
57
58#[cfg(creusot)]
59impl<T: ?Sized> DerefLogic for Snapshot<T> {
60 #[logic]
61 #[builtin("identity")]
62 fn deref_logic(&self) -> &T {
63 dead
64 }
65}
66
67#[cfg(creusot)]
68impl<T: ?Sized> DerefMutLogic for Snapshot<T> {
69 #[logic]
70 #[builtin("identity")]
71 fn deref_mut_logic(&mut self) -> &mut T {
72 dead
73 }
74}
75
76impl<T: ?Sized + Fin> Fin for Snapshot<T> {
77 type Target = T::Target;
78
79 #[logic(open, prophetic, inline)]
80 fn fin<'a>(self) -> &'a Self::Target {
81 pearlite! { &^*self }
82 }
83}
84
85impl<T: ?Sized> Clone for Snapshot<T> {
86 #[check(ghost)]
87 #[ensures(result == *self)]
88 fn clone(&self) -> Self {
89 *self
90 }
91}
92
93impl<T: ?Sized> Copy for Snapshot<T> {}
94
95#[cfg(creusot)]
96#[trusted]
97impl<T> Objective for Snapshot<T> {}
98
99impl<T: ?Sized> Snapshot<T> {
100 #[logic]
102 #[builtin("identity")]
103 pub fn new(value: T) -> Snapshot<T> {
104 let _ = value;
105 dead
106 }
107}
108
109impl<T> Snapshot<T> {
110 #[logic]
122 #[builtin("identity")]
123 pub fn inner(self) -> T {
124 dead
125 }
126
127 #[doc(hidden)]
129 #[cfg(not(creusot))]
130 pub fn from_fn(_: fn() -> T) -> Self {
131 Snapshot(PhantomData)
132 }
133
134 #[requires(inv(*self))]
136 #[ensures(*result == *self)]
137 #[check(ghost)]
138 pub fn into_ghost(self) -> Ghost<T>
139 where
140 T: Plain,
141 {
142 T::into_ghost(self)
143 }
144}