1use crate::{logic::ops::Fin, prelude::*};
19use core::{
20 marker::PhantomData,
21 ops::{Deref, DerefMut},
22};
23
24mod fn_ghost;
25pub mod invariant;
26pub mod resource;
27pub use fn_ghost::{FnGhost, FnGhostWrapper};
28pub mod perm;
29pub use perm::Container;
30
31#[opaque]
50#[intrinsic("ghost")]
51
52pub struct Ghost<T: ?Sized>(PhantomData<T>);
53
54impl<T: Copy> Copy for Ghost<T> {}
55
56impl<T: Clone + Copy> Clone for Ghost<T> {
59 #[check(ghost)]
60 #[ensures(result == *self)]
61 fn clone(&self) -> Self {
62 ghost!(**self)
63 }
64}
65
66impl<T: ?Sized> Deref for Ghost<T> {
67 type Target = T;
68
69 #[trusted]
71 #[check(ghost)]
72 #[requires(false)] #[ensures(result == &**self)]
74 #[intrinsic("ghost_deref")]
75 fn deref(&self) -> &Self::Target {
76 panic!()
77 }
78}
79impl<T: ?Sized> DerefMut for Ghost<T> {
80 #[trusted]
82 #[check(ghost)]
83 #[requires(false)] #[ensures(result == &mut **self)]
85 #[intrinsic("ghost_deref_mut")]
86 fn deref_mut(&mut self) -> &mut Self::Target {
87 panic!()
88 }
89}
90
91impl<T: ?Sized + Fin> Fin for Ghost<T> {
92 type Target = T::Target;
93
94 #[logic(open, prophetic, inline)]
95 fn fin<'a>(self) -> &'a Self::Target {
96 pearlite! { &^*self }
97 }
98}
99
100impl<T: ?Sized> Invariant for Ghost<T> {
101 #[logic(open, prophetic, inline)]
102 #[creusot::trusted_trivial_if_param_trivial]
103 fn invariant(self) -> bool {
104 inv(*self)
105 }
106}
107
108impl<T: ?Sized> Ghost<T> {
109 #[trusted]
111 #[erasure(_)]
112 #[check(ghost)]
113 #[ensures(**result == **self)]
114 pub fn borrow(&self) -> Ghost<&T> {
115 Ghost::conjure()
116 }
117
118 #[trusted]
120 #[erasure(_)]
121 #[check(ghost)]
122 #[ensures(*result == &mut **self)]
123 pub fn borrow_mut(&mut self) -> Ghost<&mut T> {
124 Ghost::conjure()
125 }
126
127 #[trusted]
134 #[erasure(_)]
135 #[check(ghost)]
136 #[requires(false)]
137 pub fn conjure() -> Self {
138 Ghost(PhantomData)
139 }
140
141 #[cfg(not(creusot))]
143 #[doc(hidden)]
144 pub fn from_fn(_: impl FnOnce() -> T) -> Self {
145 Ghost::conjure()
146 }
147}
148
149impl<T: ?Sized> Ghost<T> {
150 #[trusted]
154 #[check(ghost)]
155 #[ensures(*result == x)]
156 #[intrinsic("ghost_new")]
157 pub fn new(x: T) -> Self
158 where
159 T: Sized,
160 {
161 let _ = x;
162 panic!()
163 }
164
165 #[trusted]
166 #[logic(opaque)]
167 #[ensures(*result == x)]
168 pub fn new_logic(x: T) -> Self {
169 dead
170 }
171
172 #[trusted]
176 #[check(ghost)]
177 #[ensures(result == *self)]
178 #[intrinsic("ghost_into_inner")]
179 pub fn into_inner(self) -> T
180 where
181 T: Sized,
182 {
183 panic!()
184 }
185
186 #[logic]
190 #[builtin("identity")]
191 pub fn inner_logic(self) -> T
192 where
193 T: Sized,
194 {
195 dead
196 }
197}
198
199impl<T, U: ?Sized> Ghost<(T, U)> {
200 #[check(ghost)]
201 #[trusted]
202 #[erasure(_)]
203 #[ensures((*self).0 == *result.0)]
204 #[ensures((*self).1 == *result.1)]
205 pub fn split(self) -> (Ghost<T>, Ghost<U>) {
206 (Ghost::conjure(), Ghost::conjure())
207 }
208}
209
210pub trait Plain: Copy {
219 #[ensures(*result == *snap)]
220 #[check(ghost)]
221 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self>;
222}
223
224impl Plain for bool {
225 #[trusted]
226 #[ensures(*result == *snap)]
227 #[check(ghost)]
228 #[allow(unused_variables)]
229 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
230 Ghost::conjure()
231 }
232}
233
234impl<T> Plain for *const T {
235 #[trusted]
236 #[ensures(*result == *snap)]
237 #[check(ghost)]
238 #[allow(unused_variables)]
239 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
240 Ghost::conjure()
241 }
242}
243
244impl<T> Plain for *mut T {
245 #[trusted]
246 #[ensures(*result == *snap)]
247 #[check(ghost)]
248 #[allow(unused_variables)]
249 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
250 Ghost::conjure()
251 }
252}
253
254#[opaque]
257pub struct Committer<C: Container<Value: Sized>>(PhantomData<C>);
258
259impl<C: Container<Value: Sized>> Committer<C> {
260 #[logic(opaque)]
262 pub fn shot(self) -> bool {
263 dead
264 }
265
266 #[logic(opaque)]
270 pub fn ward(self) -> C {
271 dead
272 }
273
274 #[logic(opaque)]
276 pub fn old_value(self) -> C::Value {
277 dead
278 }
279
280 #[logic(opaque)]
282 pub fn new_value(self) -> C::Value {
283 dead
284 }
285
286 #[requires(!self.shot())]
290 #[requires(self.ward() == *own.ward())]
291 #[ensures((^self).shot())]
292 #[ensures((^own).ward() == (*own).ward())]
293 #[ensures(*(*own).val() == (*self).old_value())]
294 #[ensures(*(^own).val() == (*self).new_value())]
295 #[check(ghost)]
296 #[trusted]
297 #[allow(unused_variables)]
298 pub fn shoot(&mut self, own: &mut perm::Perm<C>) {
299 panic!("Should not be called outside ghost code")
300 }
301}