vstd_extra/
undroppable.rs1use crate::external::manually_drop::*;
2use core::mem::ManuallyDrop;
3use core::ops::Deref;
4use vstd::prelude::*;
5
6verus! {
7
8pub trait Undroppable {
9 type State;
10
11 spec fn constructor_requires(self, s: Self::State) -> bool;
12
13 spec fn constructor_ensures(self, s0: Self::State, s1: Self::State) -> bool;
14
15 #[verifier::returns(proof)]
16 proof fn constructor_spec(self, tracked s: &mut Self::State)
17 requires
18 self.constructor_requires(*old(s)),
19 ensures
20 self.constructor_ensures(*old(s), *s),
21 ;
22}
23
24pub struct NeverDrop<T: Undroppable>(pub ManuallyDrop<T>);
25
26impl<T: Undroppable> NeverDrop<T> {
27 #[verifier::external_body]
28 pub fn new(t: T, Tracked(s): Tracked<&mut T::State>) -> (res: Self)
29 requires
30 t.constructor_requires(*old(s)),
31 ensures
32 t.constructor_ensures(*old(s), *s),
33 res.0@ == t,
34 {
35 proof {
36 t.constructor_spec(s);
37 }
38 Self(ManuallyDrop::new(t))
39 }
40}
41
42impl<T: Undroppable> Deref for NeverDrop<T> {
43 type Target = T;
44
45 #[verifier::external_body]
46 fn deref(&self) -> (res: &Self::Target)
47 ensures
48 res == manually_drop_deref_spec(&self.0),
49 {
50 &self.0
51 }
52}
53
54impl<T: Undroppable> View for NeverDrop<T> {
55 type V = T;
56
57 open spec fn view(&self) -> (res: Self::V) {
58 *manually_drop_deref_spec(&self.0)
59 }
60}
61
62}