1use vstd::prelude::*;
2
3use vstd::raw_ptr::MemContents;
4use vstd::simple_pptr::{self, PPtr};
5use vstd::std_specs::convert::{FromSpec, FromSpecImpl};
6
7use core::marker::PhantomData;
8
9verus! {
10
11pub trait Repr<R: Sized>: Sized {
13 type ReprPerm;
15
16 spec fn wf(r: R, perm: Self::ReprPerm) -> bool;
17
18 spec fn to_repr_spec(self, perm: Self::ReprPerm) -> (R, Self::ReprPerm);
19
20 fn to_repr(self, Tracked(perm): Tracked<&mut Self::ReprPerm>) -> (res: R)
21 ensures
22 res == self.to_repr_spec(*old(perm)).0,
23 *final(perm) == self.to_repr_spec(*old(perm)).1,
24 ;
25
26 spec fn from_repr_spec(r: R, perm: Self::ReprPerm) -> Self;
27
28 fn from_repr(r: R, Tracked(perm): Tracked<&Self::ReprPerm>) -> (res: Self)
29 requires
30 Self::wf(r, *perm),
31 returns
32 Self::from_repr_spec(r, *perm),
33 ;
34
35 fn from_borrowed<'a>(r: &'a R, Tracked(perm): Tracked<&'a Self::ReprPerm>) -> (res: &'a Self)
36 requires
37 Self::wf(*r, *perm),
38 ensures
39 *res == Self::from_repr_spec(*r, *perm),
40 ;
41
42 fn from_borrowed_mut<'a>(r: &'a mut R, Tracked(perm): Tracked<&'a mut Self::ReprPerm>) -> (res:
47 &'a mut Self)
48 requires
49 Self::wf(*old(r), *old(perm)),
50 ensures
51 *res == Self::from_repr_spec(*old(r), *old(perm)),
52 Self::wf(*final(r), *final(perm)),
53 *final(res) == Self::from_repr_spec(*final(r), *final(perm)),
54 ;
55
56 proof fn from_to_repr(self, perm: Self::ReprPerm)
57 ensures
58 Self::from_repr_spec(self.to_repr_spec(perm).0, self.to_repr_spec(perm).1) == self,
59 ;
60
61 proof fn to_from_repr(r: R, perm: Self::ReprPerm)
62 requires
63 Self::wf(r, perm),
64 ensures
65 Self::from_repr_spec(r, perm).to_repr_spec(perm) == (r, perm),
66 ;
67
68 proof fn to_repr_wf(self, perm: Self::ReprPerm)
69 ensures
70 Self::wf(self.to_repr_spec(perm).0, self.to_repr_spec(perm).1),
71 ;
72}
73
74#[verifier::accept_recursive_types(T)]
77pub struct ReprPtr<R, T> {
78 pub ptr: PPtr<R>,
79 pub _T: PhantomData<T>,
80}
81
82impl<R, T> Clone for ReprPtr<R, T> {
83 fn clone(&self) -> Self
84 returns
85 self,
86 {
87 Self { ptr: self.ptr, _T: PhantomData }
88 }
89}
90
91impl<R, T> Copy for ReprPtr<R, T> {
92
93}
94
95impl<R, T> FromSpecImpl<PPtr<R>> for ReprPtr<R, T> {
96 open spec fn obeys_from_spec() -> bool {
97 true
98 }
99
100 open spec fn from_spec(ptr: PPtr<R>) -> Self {
101 Self { ptr, _T: PhantomData }
102 }
103}
104
105impl<R, T> From<PPtr<R>> for ReprPtr<R, T> {
106 fn from(ptr: PPtr<R>) -> Self {
107 Self { ptr, _T: PhantomData }
108 }
109}
110
111impl<R, T> FromSpecImpl<ReprPtr<R, T>> for PPtr<R> {
112 open spec fn obeys_from_spec() -> bool {
113 true
114 }
115
116 open spec fn from_spec(ptr: ReprPtr<R, T>) -> Self {
117 ptr.ptr
118 }
119}
120
121impl<R, T> From<ReprPtr<R, T>> for PPtr<R> {
122 fn from(ptr: ReprPtr<R, T>) -> Self {
123 ptr.ptr
124 }
125}
126
127impl<R, T> ReprPtr<R, T> {
128 pub open spec fn new_spec(ptr: PPtr<R>) -> Self {
129 Self { ptr, _T: PhantomData }
130 }
131
132 pub fn from_pptr(ptr: PPtr<R>) -> (res: Self)
133 ensures
134 res == Self::new_spec(ptr),
135 res.addr() == ptr.addr(),
136 res.ptr == ptr,
137 {
138 Self { ptr, _T: PhantomData }
139 }
140
141 pub open spec fn to_pptr(self) -> PPtr<R> {
142 self.ptr
143 }
144
145 pub open spec fn addr_spec(self) -> usize {
146 self.ptr.addr()
147 }
148
149 #[verifier::when_used_as_spec(addr_spec)]
150 pub fn addr(self) -> usize
151 returns
152 self.addr(),
153 {
154 self.ptr.addr()
155 }
156}
157
158impl<R, T: Repr<R>> ReprPtr<R, T> {
159 pub fn take(self, Tracked(perm): Tracked<&mut PointsTo<R, T>>) -> (v: T)
160 requires
161 old(perm).pptr() == self,
162 old(perm).is_init(),
163 old(perm).wf(&old(perm).inner_perms),
164 ensures
165 final(perm).pptr() == old(perm).pptr(),
166 final(perm).mem_contents() == MemContents::Uninit::<T>,
167 v == old(perm).value(),
168 final(perm).inner_perms == old(perm).inner_perms,
169 {
170 proof {
171 T::from_to_repr(perm.value(), perm.inner_perms);
172 }
173 T::from_repr(self.ptr.take(Tracked(&mut perm.points_to)), Tracked(&perm.inner_perms))
174 }
175
176 pub fn put(self, Tracked(perm): Tracked<&mut PointsTo<R, T>>, v: T)
177 requires
178 old(perm).pptr() == self,
179 old(perm).mem_contents() == MemContents::Uninit::<T>,
180 ensures
181 final(perm).pptr() == old(perm).pptr(),
182 final(perm).mem_contents() == MemContents::Init(v),
183 final(perm).wf(&final(perm).inner_perms),
184 final(perm).inner_perms == v.to_repr_spec(old(perm).inner_perms).1,
185 final(perm).points_to.value() == v.to_repr_spec(old(perm).inner_perms).0,
186 final(perm).points_to.is_init(),
187 {
188 proof {
189 v.from_to_repr(perm.inner_perms);
190 v.to_repr_wf(perm.inner_perms);
191 }
192 self.ptr.put(Tracked(&mut perm.points_to), v.to_repr(Tracked(&mut perm.inner_perms)))
193 }
194
195 pub fn borrow<'a>(self, Tracked(perm): Tracked<&'a PointsTo<R, T>>) -> (v: &'a T)
196 requires
197 perm.pptr() == self,
198 perm.is_init(),
199 perm.wf(&perm.inner_perms),
200 ensures
201 *v == perm.value(),
202 {
203 T::from_borrowed(self.ptr.borrow(Tracked(&perm.points_to)), Tracked(&perm.inner_perms))
204 }
205
206 #[verifier::external_body]
216 pub fn borrow_mut<'a>(self, Tracked(perm): Tracked<&'a mut PointsTo<R, T>>) -> (v: &'a mut T)
217 requires
218 old(perm).pptr() == self,
219 old(perm).is_init(),
220 old(perm).wf(&old(perm).inner_perms),
221 ensures
222 *v == old(perm).value(),
223 final(perm).pptr() == old(perm).pptr(),
224 final(perm).is_init(),
225 final(perm).wf(&final(perm).inner_perms),
226 final(perm).value() == *final(v),
227 {
228 unsafe { &mut *(self.ptr.addr() as *mut T) }
231 }
232}
233
234#[verifier::accept_recursive_types(T)]
235pub tracked struct PointsTo<R, T: Repr<R>> {
236 pub points_to: simple_pptr::PointsTo<R>,
237 pub inner_perms: T::ReprPerm,
238 pub _T: PhantomData<T>,
239}
240
241impl<R, T: Repr<R>> PointsTo<R, T> {
242 pub open spec fn new_spec(
243 points_to: simple_pptr::PointsTo<R>,
244 inner_perms: T::ReprPerm,
245 ) -> Self {
246 Self { points_to, inner_perms, _T: PhantomData }
247 }
248
249 pub proof fn new(
250 tracked points_to: simple_pptr::PointsTo<R>,
251 tracked inner_perms: T::ReprPerm,
252 ) -> (tracked res: Self)
253 returns
254 Self::new_spec(points_to, inner_perms),
255 {
256 Self { points_to, inner_perms, _T: PhantomData }
257 }
258
259 pub open spec fn wf(self, perm: &T::ReprPerm) -> bool {
260 &&& T::wf(self.points_to.value(), *perm)
261 }
262
263 pub open spec fn addr(self) -> usize {
264 self.points_to.addr()
265 }
266
267 pub open spec fn mem_contents(self) -> MemContents<T> {
268 match self.points_to.mem_contents() {
269 MemContents::<R>::Uninit => MemContents::<T>::Uninit,
270 MemContents::<R>::Init(r) => MemContents::<T>::Init(
271 T::from_repr_spec(r, self.inner_perms),
272 ),
273 }
274 }
275
276 pub open spec fn is_init(self) -> bool {
277 self.mem_contents().is_init()
278 }
279
280 pub open spec fn is_uninit(self) -> bool {
281 self.mem_contents().is_uninit()
282 }
283
284 pub open spec fn value(self) -> T
285 recommends
286 self.is_init(),
287 {
288 self.mem_contents().value()
289 }
290
291 pub open spec fn pptr(self) -> ReprPtr<R, T> {
292 ReprPtr { ptr: self.points_to.pptr(), _T: PhantomData }
293 }
294}
295
296}