creusot_contracts/ghost/
fn_ghost.rs1use crate::*;
3
4mod private {
5 pub trait _Sealed {}
7}
8
9#[intrinsic("fn_ghost")]
14pub trait FnGhost: private::_Sealed {}
15
16#[cfg(not(creusot))]
18impl<F> private::_Sealed for F {}
19#[cfg(not(creusot))]
20impl<F> FnGhost for F {}
21
22#[doc(hidden)]
27#[intrinsic("fn_ghost_wrapper")]
28pub struct FnGhostWrapper<F>(F);
29
30impl<F: Clone> Clone for FnGhostWrapper<F> {
31 #[ensures(F::clone.postcondition((&self@,), result@))]
32 fn clone(&self) -> Self {
33 Self(self.0.clone())
34 }
35}
36impl<F: Copy> Copy for FnGhostWrapper<F> {}
37
38#[cfg(creusot)]
39impl<I: ::std::marker::Tuple, F: FnOnce<I>> FnOnce<I> for FnGhostWrapper<F> {
40 type Output = F::Output;
41
42 #[trusted]
43 #[requires(self.precondition(args))]
44 #[ensures(self.postcondition_once(args, result))]
45 #[check(ghost)]
46 extern "rust-call" fn call_once(self, args: I) -> Self::Output {
47 self.0.call_once(args)
48 }
49}
50#[cfg(creusot)]
51impl<I: ::std::marker::Tuple, F: FnMut<I>> FnMut<I> for FnGhostWrapper<F> {
52 #[trusted]
53 #[requires((*self).precondition(args))]
54 #[ensures((*self).postcondition_mut(args, ^self, result))]
55 #[check(ghost)]
56 extern "rust-call" fn call_mut(&mut self, args: I) -> Self::Output {
57 self.0.call_mut(args)
58 }
59}
60#[cfg(creusot)]
61impl<I: ::std::marker::Tuple, F: Fn<I>> Fn<I> for FnGhostWrapper<F> {
62 #[trusted]
63 #[requires((*self).precondition(args))]
64 #[ensures((*self).postcondition(args, result))]
65 #[check(ghost)]
66 extern "rust-call" fn call(&self, args: I) -> Self::Output {
67 self.0.call(args)
68 }
69}
70
71impl<F> FnGhostWrapper<F> {
72 #[doc(hidden)]
75 #[check(ghost)]
76 #[ensures(result@ == f)]
77 pub fn __new(f: F) -> Self {
78 Self(f)
79 }
80}
81impl<F> View for FnGhostWrapper<F> {
82 type ViewTy = F;
83
84 #[logic(inline)]
85 fn view(self) -> Self::ViewTy {
86 self.0
87 }
88}
89#[cfg(creusot)]
90impl<F> private::_Sealed for FnGhostWrapper<F> {}
91#[cfg(creusot)]
92impl<F> FnGhost for FnGhostWrapper<F> {}