vstd_extra/
drop_tracking.rs1use core::{marker::PhantomData, ops::Deref};
2use vstd::prelude::*;
3
4verus! {
5
6pub trait TrackDrop {
7 type State;
8
9 spec fn constructor_requires(self, s: Self::State) -> bool;
10
11 spec fn constructor_ensures(self, s0: Self::State, s1: Self::State) -> bool;
12
13 #[verifier::returns(proof)]
14 proof fn constructor_spec(self, tracked s: &mut Self::State)
15 requires
16 self.constructor_requires(*old(s)),
17 ensures
18 self.constructor_ensures(*old(s), *s),
19 ;
20
21 spec fn drop_requires(self, s: Self::State) -> bool;
22
23 spec fn drop_ensures(self, s0: Self::State, s1: Self::State) -> bool;
24
25 proof fn drop_spec(self, tracked s: &mut Self::State)
26 requires
27 self.drop_requires(*old(s)),
28 ensures
29 self.drop_ensures(*old(s), *s),
30 ;
31}
32
33pub struct ManuallyDrop<T: TrackDrop>(pub T);
34
35impl<T: TrackDrop> ManuallyDrop<T> {
36 #[verifier::external_body]
37 pub fn new(t: T, Tracked(s): Tracked<&mut T::State>) -> (res: Self)
38 requires
39 t.constructor_requires(*old(s)),
40 ensures
41 t.constructor_ensures(*old(s), *s),
42 res.0 == t,
43 {
44 proof {
45 t.constructor_spec(s);
46 }
47 Self(t)
48 }
49
50 pub fn drop(self, Tracked(s): Tracked<&mut T::State>)
51 requires
52 self.0.drop_requires(*old(s)),
53 ensures
54 self.0.drop_ensures(*old(s), *s),
55 {
56 proof {
57 self.0.drop_spec(s);
58 }
59 }
61}
62
63impl<T: TrackDrop> Deref for ManuallyDrop<T> {
64 type Target = T;
65
66 #[verifier::external_body]
67 fn deref(&self) -> (res: &Self::Target)
68 ensures
69 res == &self.0,
70 {
71 &self.0
72 }
73}
74
75impl<T: TrackDrop> View for ManuallyDrop<T> {
76 type V = T;
77
78 open spec fn view(&self) -> (res: Self::V) {
79 self.0
80 }
81}
82
83}