@@ -57,6 +57,7 @@ pub unsafe trait NonNullPtr: Sized +'static {
5757 /// SOUNDNESS: Considering also returning the Dealloc permission to ensure no memory leak.
5858 fn into_raw( self ) -> ( ret: ( NonNull <Self :: Target >, Tracked <SmartPtrPointsTo <Self :: Target >>) )
5959 ensures
60+ ptr_mut_from_nonull( ret. 0 ) == self . ptr_mut_spec( ) ,
6061 ptr_mut_from_nonull( ret. 0 ) == ret. 1 @. ptr( ) ,
6162 ret. 1 @. inv( ) ,
6263 Self :: match_points_to_type( ret. 1 @) ,
@@ -78,11 +79,13 @@ pub unsafe trait NonNullPtr: Sized +'static {
7879 /// so we can do nothing with the raw pointer because of the absence of permission.
7980 /// VERUS LIMITATION: the #[verus_spec] attribute does not support `with` in trait yet.
8081 /// SOUNDNESS: Considering consuming the Dealloc permission to ensure no double free.
81- unsafe fn from_raw( ptr: NonNull <Self :: Target >, perm: Tracked <SmartPtrPointsTo <Self :: Target >>) -> Self
82+ unsafe fn from_raw( ptr: NonNull <Self :: Target >, perm: Tracked <SmartPtrPointsTo <Self :: Target >>) -> ( ret : Self )
8283 requires
8384 Self :: match_points_to_type( perm@) ,
8485 ptr_mut_from_nonull( ptr) == perm@. ptr( ) ,
8586 perm@. inv( ) ,
87+ ensures
88+ ptr_mut_from_nonull( ptr) == ret. ptr_mut_spec( ) ,
8689 ;
8790
8891 // VERUS LIMITATION: Cannot use associated type with lifetime yet, will implement it as a free function for each type.
@@ -99,6 +102,9 @@ pub unsafe trait NonNullPtr: Sized +'static {
99102 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> NonNull<Self::Target>;*/
100103
101104 spec fn match_points_to_type( perm: SmartPtrPointsTo <Self :: Target >) -> bool ;
105+
106+ // A uninterpreted spec function that returns the inner raw pointer.
107+ spec fn ptr_mut_spec( self ) -> * mut Self :: Target ;
102108}
103109
104110/// A type that represents `&'a Box<T>`.
@@ -122,6 +128,10 @@ impl<'a, T> BoxRef<'a, T> {
122128 pub closed spec fn ptr( self ) -> * mut T {
123129 self . inner
124130 }
131+
132+ pub closed spec fn value( self ) -> T {
133+ self . v_perm@. value( )
134+ }
125135}
126136
127137/*
@@ -138,16 +148,24 @@ impl<T> Deref for BoxRef<'_, T> {
138148 }
139149}
140150*/
141- /*
151+
152+ #[ verus_verify]
142153impl <' a, T > BoxRef <' a, T > {
143154 /// Dereferences `self` to get a reference to `T` with the lifetime `'a`.
155+ #[ verus_spec( ret => ensures * ret == self . value( ) ) ]
144156 pub fn deref_target( & self ) -> & ' a T {
145- // SAFETY: The reference is created through `NonNullPtr::raw_as_ref`, hence
157+ // [VERIFIED] SAFETY: The reference is created through `NonNullPtr::raw_as_ref`, hence
146158 // the original owned pointer and target must outlive the lifetime parameter `'a`,
147159 // and during `'a` no mutable references to the pointer will exist.
148- unsafe { &*(self.inner) }
160+
161+ let Tracked ( perm) = self . v_perm;
162+ proof!{
163+ use_type_invariant( self ) ;
164+ }
165+ //unsafe { &*(self.inner) }
166+ vstd:: raw_ptr:: ptr_ref( self . inner, Tracked ( perm. tracked_borrow_points_to( ) ) ) // The function body of ptr_ref is exactly the same as `unsafe { &*(self.inner) }`
149167 }
150- }*/
168+ }
151169
152170#[ verus_verify]
153171unsafe impl <T : ' static > NonNullPtr for Box <T > {
@@ -176,7 +194,7 @@ unsafe impl<T: 'static> NonNullPtr for Box<T> {
176194
177195 unsafe fn from_raw( ptr: NonNull <Self :: Target >, Tracked ( perm) : Tracked <SmartPtrPointsTo <Self :: Target >>) -> Self {
178196 proof_decl!{
179- let tracked perm = perm. get_box_points_to( ) . tracked_get_perm ( ) ;
197+ let tracked perm = perm. get_box_points_to( ) . tracked_get_points_to_with_dealloc ( ) ;
180198 }
181199 let ptr = ptr. as_ptr( ) ;
182200
@@ -200,6 +218,10 @@ unsafe impl<T: 'static> NonNullPtr for Box<T> {
200218 open spec fn match_points_to_type( perm: SmartPtrPointsTo <Self :: Target >) -> bool {
201219 perm is Box
202220 }
221+
222+ open spec fn ptr_mut_spec( self ) -> * mut Self :: Target {
223+ box_pointer_spec( self )
224+ }
203225}
204226
205227pub fn box_ref_as_raw<T : ' static >( ptr_ref: BoxRef <' _ , T >) -> ( ret: ( NonNull <T >, Tracked <& BoxPointsTo <T >>) )
@@ -233,20 +255,47 @@ pub unsafe fn box_raw_as_ref<'a, T: 'static>(raw: NonNull<T>, perm: Tracked<&'a
233255/// A type that represents `&'a Arc<T>`.
234256 #[ verus_verify]
235257#[ derive( Debug ) ]
236- pub struct ArcRef <' a, T > {
258+ pub struct ArcRef <' a, T : ' static > {
237259 inner: ManuallyDrop <Arc <T >>,
238260 _marker: PhantomData <& ' a Arc <T >>,
261+ v_perm: Tracked <ArcPointsTo <T >>,
239262}
240263
241- /*
264+ impl <' a, T > ArcRef <' a, T > {
265+ #[ verifier:: type_invariant]
266+ spec fn type_inv( self ) -> bool {
267+ &&& self . ptr( ) == self . v_perm@. ptr( )
268+ &&& self . v_perm@. inv( )
269+ &&& self . ptr( ) @. addr != 0
270+ &&& self . ptr( ) @. addr as int % vstd:: layout:: align_of:: <T >( ) as int == 0
271+ }
272+
273+ pub open spec fn ptr( self ) -> * const T {
274+ arc_pointer_spec( * self . deref_as_arc_spec( ) )
275+ }
276+
277+ pub closed spec fn deref_as_arc_spec( & self ) -> & Arc <T > {
278+ manually_drop_deref_spec( & self . inner)
279+ }
280+
281+ /// A workaround that Verus does not support implementing spec for Deref trait yet.
282+ pub broadcast axiom fn arcref_deref_spec_eq( self )
283+ ensures
284+ #[ trigger] self . deref_as_arc_spec( ) == #[ trigger] self . deref_spec( ) ,
285+ ;
286+ }
287+
288+ #[ verus_verify]
242289impl <T > Deref for ArcRef <' _, T > {
243290 type Target = Arc <T >;
244291
292+ #[ verus_verify]
245293 fn deref( & self ) -> & Self :: Target {
246294 & self . inner
247295 }
248296}
249297
298+ /*
250299impl<'a, T> ArcRef<'a, T> {
251300 /// Dereferences `self` to get a reference to `T` with the lifetime `'a`.
252301 pub fn deref_target(&self) -> &'a T {
@@ -313,6 +362,26 @@ unsafe impl<T: 'static> NonNullPtr for Arc<T> {
313362 open spec fn match_points_to_type( perm: SmartPtrPointsTo <Self :: Target >) -> bool {
314363 perm is Arc
315364 }
365+
366+ open spec fn ptr_mut_spec( self ) -> * mut Self :: Target {
367+ arc_pointer_spec( self ) as * mut Self :: Target
368+ }
369+ }
370+
371+ pub fn arc_ref_as_raw<T : ' static >( ptr_ref: ArcRef <' _ , T >) -> ( ret: ( NonNull <T >, Tracked <ArcPointsTo <T >>) )
372+ ensures
373+ ret. 0 == nonnull_from_ptr_mut( ptr_ref. ptr( ) as * mut T ) ,
374+ ret. 1 @. ptr( ) . addr( ) != 0 ,
375+ ret. 1 @. ptr( ) . addr( ) as int % vstd:: layout:: align_of:: <T >( ) as int == 0 ,
376+ ret. 1 @. ptr( ) == ptr_mut_from_nonull( ret. 0 ) ,
377+ ret. 1 @. inv( ) ,
378+ {
379+ proof!{
380+ use_type_invariant( & ptr_ref) ;
381+ }
382+ // NonNullPtr::into_raw(ManuallyDrop::into_inner(ptr_ref.inner))
383+ let ( ptr, Tracked ( perm) ) = NonNullPtr :: into_raw( ManuallyDrop :: into_inner( ptr_ref. inner) ) ;
384+ ( ptr, Tracked ( perm. get_arc_points_to( ) ) )
316385}
317386
318387/*
0 commit comments