1mod fn_ghost;
19pub mod invariant;
20pub mod lifetime_logic;
21pub mod perm;
22pub mod resource;
23mod shared;
24
25pub use self::{
26 fn_ghost::{FnGhost, FnGhostWrapper},
27 perm::PermTarget,
28 shared::GhostShared,
29};
30
31#[cfg(creusot)]
32use crate::resolve::{resolve, structural_resolve};
33use crate::{logic::ops::Fin, prelude::*};
34
35use core::{
36 marker::PhantomData,
37 ops::{Deref, DerefMut},
38};
39
40#[intrinsic("ghost")]
59#[builtin("identity")]
60pub struct Ghost<T: ?Sized>(PhantomData<T>);
61
62impl<T: Copy> Copy for Ghost<T> {}
63
64impl<T: Clone + Copy> Clone for Ghost<T> {
67 #[check(ghost)]
68 #[ensures(result == *self)]
69 fn clone(&self) -> Self {
70 ghost!(**self)
71 }
72}
73
74impl<T: ?Sized> Deref for Ghost<T> {
75 type Target = T;
76
77 #[trusted]
79 #[check(ghost)]
80 #[requires(false)] #[ensures(result == &**self)]
82 #[intrinsic("ghost_deref")]
83 fn deref(&self) -> &Self::Target {
84 panic!()
85 }
86}
87impl<T: ?Sized> DerefMut for Ghost<T> {
88 #[trusted]
90 #[check(ghost)]
91 #[requires(false)] #[ensures(result == &mut **self)]
93 #[intrinsic("ghost_deref_mut")]
94 fn deref_mut(&mut self) -> &mut Self::Target {
95 panic!()
96 }
97}
98
99impl<T: ?Sized + Fin> Fin for Ghost<T> {
100 type Target = T::Target;
101
102 #[logic(open, prophetic, inline)]
103 fn fin<'a>(self) -> &'a Self::Target {
104 pearlite! { &^*self }
105 }
106}
107
108impl<T: ?Sized> Invariant for Ghost<T> {
109 #[logic(open, prophetic, inline)]
110 #[creusot::trusted_trivial_if_param_trivial]
111 fn invariant(self) -> bool {
112 inv(*self)
113 }
114}
115
116impl<'a, T: ?Sized> Resolve for Ghost<T> {
117 #[logic(open, inline, prophetic)]
118 #[creusot::trusted_trivial_if_param_trivial]
119 fn resolve(self) -> bool {
120 resolve(*self)
121 }
122
123 #[trusted]
124 #[logic]
125 #[requires(structural_resolve(self))]
126 #[ensures(self.resolve())]
127 fn resolve_coherence(self) {}
128}
129
130impl<T: ?Sized> Ghost<T> {
131 #[trusted]
133 #[erasure(_)]
134 #[check(ghost)]
135 #[ensures(**result == **self)]
136 pub fn borrow(&self) -> Ghost<&T> {
137 Ghost::conjure()
138 }
139
140 #[trusted]
142 #[erasure(_)]
143 #[check(ghost)]
144 #[ensures(*result == &mut **self)]
145 pub fn borrow_mut(&mut self) -> Ghost<&mut T> {
146 Ghost::conjure()
147 }
148
149 #[trusted]
156 #[erasure(_)]
157 #[check(ghost)]
158 #[requires(false)]
159 pub fn conjure() -> Self {
160 Ghost(PhantomData)
161 }
162
163 #[cfg(not(creusot))]
165 #[doc(hidden)]
166 pub fn from_fn(_: impl FnOnce() -> T) -> Self {
167 Ghost::conjure()
168 }
169}
170
171impl<T: ?Sized> Ghost<T> {
172 #[trusted]
176 #[check(ghost)]
177 #[ensures(*result == x)]
178 #[intrinsic("ghost_new")]
179 pub fn new(x: T) -> Self
180 where
181 T: Sized,
182 {
183 let _ = x;
184 panic!()
185 }
186
187 #[trusted]
188 #[logic(opaque)]
189 #[ensures(*result == x)]
190 pub fn new_logic(x: T) -> Self {
191 dead
192 }
193
194 #[trusted]
198 #[check(ghost)]
199 #[ensures(result == *self)]
200 #[intrinsic("ghost_into_inner")]
201 pub fn into_inner(self) -> T
202 where
203 T: Sized,
204 {
205 panic!()
206 }
207
208 #[logic]
212 #[builtin("identity")]
213 pub fn inner_logic(self) -> T
214 where
215 T: Sized,
216 {
217 dead
218 }
219}
220
221impl<T, U: ?Sized> Ghost<(T, U)> {
222 #[check(ghost)]
223 #[trusted]
224 #[erasure(_)]
225 #[ensures((*self).0 == *result.0)]
226 #[ensures((*self).1 == *result.1)]
227 pub fn split(self) -> (Ghost<T>, Ghost<U>) {
228 (Ghost::conjure(), Ghost::conjure())
229 }
230}
231
232pub trait Plain: Copy {
241 #[ensures(*result == *snap)]
242 #[check(ghost)]
243 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self>;
244}
245
246impl Plain for bool {
247 #[trusted]
248 #[ensures(*result == *snap)]
249 #[check(ghost)]
250 #[allow(unused_variables)]
251 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
252 Ghost::conjure()
253 }
254}
255
256impl<T> Plain for *const T {
257 #[trusted]
258 #[ensures(*result == *snap)]
259 #[check(ghost)]
260 #[allow(unused_variables)]
261 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
262 Ghost::conjure()
263 }
264}
265
266impl<T> Plain for *mut T {
267 #[trusted]
268 #[ensures(*result == *snap)]
269 #[check(ghost)]
270 #[allow(unused_variables)]
271 fn into_ghost(snap: Snapshot<Self>) -> Ghost<Self> {
272 Ghost::conjure()
273 }
274}
275
276#[cfg(creusot)]
279macro_rules! define_objective {
280 () => {
281 #[trusted]
286 pub auto trait Objective {}
287
288 #[trusted]
289 impl !Objective for NotObjective {}
290 };
291}
292
293#[cfg(creusot)]
294define_objective! {}
295
296pub struct NotObjective {}