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), *final(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_tracked(self, tracked s: &mut Self::State)
26 requires
27 self.drop_requires(*old(s)),
28 ensures
29 self.drop_ensures(*old(s), *final(s)),
30 ;
31}
32
33pub trait Drop: TrackDrop {
34 fn drop(self, Tracked(s): Tracked<Self::State>) -> (res: Tracked<Self::State>)
35 requires
36 self.drop_requires(s),
37 ensures
38 self.drop_ensures(s, res@),
39 ;
40}
41
42pub struct ManuallyDrop<T: TrackDrop>(pub T);
43
44impl<T: TrackDrop> ManuallyDrop<T> {
45 #[verifier::external_body]
46 pub fn new(t: T, Tracked(s): Tracked<&mut T::State>) -> (res: Self)
47 requires
48 t.constructor_requires(*old(s)),
49 ensures
50 t.constructor_ensures(*old(s), *final(s)),
51 res.0 == t,
52 {
53 proof {
54 t.constructor_spec(s);
55 }
56 Self(t)
57 }
58}
59
60impl<T: Drop> ManuallyDrop<T> {
61 pub fn drop(self, Tracked(s): Tracked<T::State>) -> (res: Tracked<T::State>)
62 requires
63 self.0.drop_requires(s),
64 ensures
65 self.0.drop_ensures(s, res@),
66 {
67 self.0.drop(Tracked(s))
68 }
69}
70
71impl<T: TrackDrop> Deref for ManuallyDrop<T> {
72 type Target = T;
73
74 #[verifier::external_body]
75 fn deref(&self) -> (res: &Self::Target)
76 ensures
77 res == &self.0,
78 {
79 &self.0
80 }
81}
82
83impl<T: TrackDrop> View for ManuallyDrop<T> {
84 type V = T;
85
86 open spec fn view(&self) -> (res: Self::V) {
87 self.0
88 }
89}
90
91}