vstd_extra/external/
smart_ptr.rs1use crate::ownership::*;
2use crate::raw_ptr_extra::*;
3use alloc::boxed::Box;
4use alloc::sync::Arc;
5use vstd::layout::valid_layout;
6use vstd::prelude::*;
7use vstd::raw_ptr::*;
8#[cfg(feature = "irc11")]
9use vstd::thread_view::Objective;
10
11verus! {
13
14pub trait PtrPointsToTrait {
16 type Ptr;
18
19 type Target;
21
22 spec fn ptr(self) -> *mut Self::Target;
23
24 spec fn view_target(self) -> Self::Target;
25}
26
27impl<T> PtrPointsToTrait for BoxPointsTo<T> {
28 type Ptr = Box<T>;
29
30 type Target = T;
31
32 open spec fn ptr(self) -> *mut T {
33 self.perm.ptr()
34 }
35
36 open spec fn view_target(self) -> T {
37 self.perm.value()
38 }
39}
40
41impl<T> PtrPointsToTrait for ArcPointsTo<T> {
42 type Ptr = Arc<T>;
43
44 type Target = T;
45
46 open spec fn ptr(self) -> *mut T {
47 self.perm.ptr()
48 }
49
50 open spec fn view_target(self) -> T {
51 self.perm.value()
52 }
53}
54
55pub tracked struct BoxPointsTo<T> {
58 pub perm: PointsTowithDealloc<T>,
59}
60
61pub tracked struct ArcPointsTo<T: 'static> {
65 pub perm: &'static PointsTo<T>,
66}
67
68#[cfg(feature = "irc11")]
71unsafe impl<T> Objective for BoxPointsTo<T> {
72
73}
74
75#[cfg(feature = "irc11")]
76unsafe impl<T> Objective for ArcPointsTo<T> {
77
78}
79
80impl<T> BoxPointsTo<T> {
81 pub open spec fn perm(self) -> PointsTowithDealloc<T> {
82 self.perm
83 }
84
85 pub open spec fn ptr(self) -> *mut T {
86 self.perm.ptr()
87 }
88
89 pub open spec fn addr(self) -> usize {
90 self.ptr().addr()
91 }
92
93 pub open spec fn is_init(self) -> bool {
94 self.perm.is_init()
95 }
96
97 pub open spec fn value(self) -> T {
98 self.perm.value()
99 }
100
101 pub proof fn tracked_get_points_to_with_dealloc(tracked self) -> (tracked ret:
102 PointsTowithDealloc<T>)
103 returns
104 self.perm,
105 {
106 self.perm
107 }
108
109 pub proof fn tracked_borrow_points_to_with_dealloc(tracked &self) -> (tracked ret:
110 &PointsTowithDealloc<T>)
111 returns
112 &self.perm,
113 {
114 &self.perm
115 }
116
117 pub proof fn tracked_get_points_to(tracked self) -> (tracked ret: PointsTo<T>)
118 returns
119 self.perm.points_to,
120 {
121 self.tracked_get_points_to_with_dealloc().tracked_get_points_to()
122 }
123
124 pub proof fn tracked_borrow_points_to(tracked &self) -> (tracked ret: &PointsTo<T>)
125 returns
126 &self.perm.points_to,
127 {
128 &self.tracked_borrow_points_to_with_dealloc().tracked_borrow_points_to()
129 }
130}
131
132impl<T> ArcPointsTo<T> {
133 pub open spec fn perm(self) -> &'static PointsTo<T> {
134 self.perm
135 }
136
137 pub open spec fn ptr(self) -> *mut T {
138 self.perm.ptr()
139 }
140
141 pub open spec fn addr(self) -> usize {
142 self.ptr().addr()
143 }
144
145 pub open spec fn is_init(self) -> bool {
146 self.perm.is_init()
147 }
148
149 pub open spec fn value(self) -> T {
150 self.perm.value()
151 }
152
153 pub proof fn tracked_borrow_points_to(tracked &self) -> (tracked ret: &'static PointsTo<T>)
154 returns
155 self.perm,
156 {
157 self.perm
158 }
159}
160
161impl<T> Inv for BoxPointsTo<T> {
162 open spec fn inv(self) -> bool {
163 &&& self.perm.inv()
164 &&& self.perm.dealloc_aligned()
165 &&& self.perm.is_init()
166 }
167}
168
169impl<T> Inv for ArcPointsTo<T> {
170 open spec fn inv(self) -> bool {
171 &&& self.addr() != 0
172 &&& self.addr() as int % vstd::layout::align_of::<T>() as int == 0
173 &&& self.perm.is_init()
174 }
175}
176
177} #[verifier::external_body]
195#[verus_spec(ret =>
196 with
197 -> perm: Tracked<(PointsTo<T>, Option<Dealloc>)>,
198 ensures
199 ret == perm@.0.ptr(),
200 perm@.0.ptr().addr() != 0,
201 perm@.0.is_init(),
202 perm@.0.ptr().addr() as int % vstd::layout::align_of::<T>() as int == 0,
203 perm@.0.value() == *b,
204 match perm@.1 {
205 Some(dealloc) => {
206 &&& vstd::layout::size_of::<T>() > 0
207 &&& dealloc.addr() == perm@.0.ptr().addr()
208 &&& dealloc.size() == vstd::layout::size_of::<T>()
209 &&& dealloc.align() == vstd::layout::align_of::<T>()
210 &&& dealloc.provenance() == perm@.0.ptr()@.provenance
211 &&& valid_layout(size_of::<T>(), align_of::<T>())
212 },
213 None => { &&& vstd::layout::size_of::<T>() == 0 },
214 }
215)]
216pub fn box_into_raw<T>(b: Box<T>) -> *mut T {
217 proof_with!(|= Tracked::assume_new());
218 Box::into_raw(b)
219}
220
221#[verifier::external_body]
222#[verus_spec(ret =>
223 with
224 Tracked(points_to): Tracked<PointsTo<T>>,
225 Tracked(dealloc): Tracked<Option<Dealloc>>,
226 requires
227 ptr@.addr != 0,
228 points_to.ptr() == ptr,
229 points_to.is_init(),
230 points_to.ptr().addr() as int % vstd::layout::align_of::<T>() as int == 0,
231 match dealloc@ {
232 Some(dealloc) => {
233 &&& vstd::layout::size_of::<T>() > 0
234 &&& dealloc.addr() == ptr@.addr
235 &&& dealloc.size() == vstd::layout::size_of::<T>()
236 &&& dealloc.align() == vstd::layout::align_of::<T>()
237 &&& dealloc.provenance() == ptr@.provenance
238 &&& valid_layout(size_of::<T>(), align_of::<T>())
239 },
240 None => { &&& vstd::layout::size_of::<T>() == 0 },
241 },
242 ensures
243 *ret == points_to.value(),
244 )]
245pub unsafe fn box_from_raw<T>(ptr: *mut T) -> Box<T> {
246 unsafe { Box::from_raw(ptr) }
247}
248
249#[verifier::external_body]
255#[verus_spec(ret =>
256 with
257 -> perm: Tracked<ArcPointsTo<T>>,
258 ensures
259 ret == perm@.ptr(),
260 perm@.ptr().addr() != 0,
261 perm@.is_init(),
262 perm@.ptr().addr() as int % vstd::layout::align_of::<T>() as int == 0,
263 perm@.value() == *p,
264)]
265pub fn arc_into_raw<T>(p: Arc<T>) -> *const T {
266 proof_with!(|= Tracked::assume_new());
267 Arc::into_raw(p)
268}
269
270#[verifier::external_body]
273#[verus_spec(ret =>
274 with
275 Tracked(points_to): Tracked<ArcPointsTo<T>>,
276 requires
277 ptr.addr() != 0,
278 points_to.ptr() == ptr,
279 points_to.is_init(),
280 points_to.ptr().addr() as int % vstd::layout::align_of::<T>() as int == 0,
281 ensures
282 *ret == points_to.value(),
283)]
284pub unsafe fn arc_from_raw<T>(ptr: *const T) -> Arc<T> {
285 unsafe { Arc::from_raw(ptr) }
286}
287
288verus! {
289
290pub tracked struct BoxPointsToRef<'a, T>(pub &'a BoxPointsTo<T>);
292
293impl<'a, T> View for BoxPointsToRef<'a, T> {
294 type V = BoxPointsTo<T>;
295
296 open spec fn view(&self) -> BoxPointsTo<T> {
297 *self.0
298 }
299}
300
301impl<'a, T> Inv for BoxPointsToRef<'a, T> {
302 open spec fn inv(self) -> bool {
303 self@.inv()
304 }
305}
306
307impl<'a, T> BoxPointsToRef<'a, T> {
308 pub proof fn tracked_borrow_points_to(tracked &self) -> (tracked ret: &'a PointsTo<T>)
309 returns
310 self@.perm.points_to,
311 {
312 self.0.tracked_borrow_points_to()
313 }
314}
315
316}