@@ -5,35 +5,117 @@ use vstd::layout::valid_layout;
55use vstd:: prelude:: * ;
66use vstd:: raw_ptr:: * ;
77
8+ // A unified interface for the raw ptr permission returned by `into_raw` methods of smart pointers like `Box` and `Arc`.
89verus ! {
910
1011// The permssion to access memory given by the `into_raw` methods of smart pointers like `Box` and `Arc`.
1112/// For Box<T>, the `into_raw` method gives you the ownership of the memory
12- pub type BoxPointsTo <T > = PointsTowithDealloc <T >;
13+ pub tracked struct BoxPointsTo <T > {
14+ pub perm: PointsTowithDealloc <T >,
15+ }
1316
1417/// For Arc<T>, the `into_raw` method gives shared access to the memory, and the reference count is not decreased,
1518/// so the value will not be deallocated until we convert back to Arc<T> and drop it.
1619/// See https://doc.rust-lang.org/src/alloc/sync.rs.html#1480.
17- pub type ArcPointsTo <T > = & ' static PointsTo <T >;
20+ pub tracked struct ArcPointsTo <T : ' static > {
21+ pub perm: & ' static PointsTo <T >,
22+ }
1823
1924pub tracked enum SmartPtrPointsTo <T : ' static > {
2025 Box ( BoxPointsTo <T >) ,
2126 Arc ( ArcPointsTo <T >) ,
2227}
2328
29+ impl <T > BoxPointsTo <T > {
30+ pub open spec fn perm( self ) -> PointsTowithDealloc <T > {
31+ self . perm
32+ }
33+
34+ pub open spec fn ptr( self ) -> * mut T {
35+ self . perm. ptr( )
36+ }
37+
38+ pub open spec fn addr( self ) -> usize {
39+ self . ptr( ) . addr( )
40+ }
41+
42+ pub open spec fn is_uninit( self ) -> bool {
43+ self . perm. is_uninit( )
44+ }
45+
46+ pub open spec fn is_init( self ) -> bool {
47+ self . perm. is_init( )
48+ }
49+
50+ pub proof fn tracked_get_perm( tracked self ) -> ( tracked ret: PointsTowithDealloc <T >)
51+ returns
52+ self . perm,
53+ {
54+ self . perm
55+ }
56+
57+ pub proof fn tracked_borrow_perm<' a>( tracked & ' a self ) -> ( tracked ret: & ' a PointsTowithDealloc <
58+ T ,
59+ >)
60+ ensures
61+ ret == & self . perm,
62+ returns
63+ & self . perm,
64+ {
65+ & self . perm
66+ }
67+ }
68+
69+ impl <T > ArcPointsTo <T > {
70+ pub open spec fn perm( self ) -> & ' static PointsTo <T > {
71+ self . perm
72+ }
73+
74+ pub open spec fn ptr( self ) -> * mut T {
75+ self . perm. ptr( )
76+ }
77+
78+ pub open spec fn addr( self ) -> usize {
79+ self . ptr( ) . addr( )
80+ }
81+
82+ pub open spec fn is_uninit( self ) -> bool {
83+ self . perm. is_uninit( )
84+ }
85+
86+ pub open spec fn is_init( self ) -> bool {
87+ self . perm. is_init( )
88+ }
89+
90+ pub proof fn tracked_get_perm( tracked self ) -> ( tracked ret: & ' static PointsTo <T >)
91+ returns
92+ self . perm,
93+ {
94+ self . perm
95+ }
96+ }
97+
98+ impl <T > Inv for BoxPointsTo <T > {
99+ open spec fn inv( self ) -> bool {
100+ &&& self . perm. inv( )
101+ &&& self . perm. dealloc_aligned( )
102+ &&& self . is_init( )
103+ }
104+ }
105+
106+ impl <T > Inv for ArcPointsTo <T > {
107+ open spec fn inv( self ) -> bool {
108+ &&& self . addr( ) != 0
109+ &&& self . addr( ) as int % vstd:: layout:: align_of:: <T >( ) as int == 0
110+ &&& self . is_init( )
111+ }
112+ }
113+
24114impl <T > Inv for SmartPtrPointsTo <T > {
25115 open spec fn inv( self ) -> bool {
26116 match self {
27- SmartPtrPointsTo :: Box ( b) => {
28- &&& b. inv( )
29- &&& b. dealloc_aligned( )
30- &&& b. is_init( )
31- } ,
32- SmartPtrPointsTo :: Arc ( a) => {
33- &&& a. ptr( ) . addr( ) != 0
34- &&& a. ptr( ) . addr( ) as int % vstd:: layout:: align_of:: <T >( ) as int == 0
35- &&& a. is_init( )
36- } ,
117+ SmartPtrPointsTo :: Box ( b) => { b. inv( ) } ,
118+ SmartPtrPointsTo :: Arc ( a) => { a. inv( ) } ,
37119 }
38120 }
39121}
@@ -70,11 +152,10 @@ impl<T> SmartPtrPointsTo<T> {
70152 returns
71153 self ->Box_0 ,
72154 {
73- let tracked option_perm = match self {
74- SmartPtrPointsTo :: Box ( p) => Some ( p) ,
75- _ => None ,
76- } ;
77- option_perm. tracked_unwrap( )
155+ match self {
156+ SmartPtrPointsTo :: Box ( p) => p,
157+ _ => proof_from_false( ) ,
158+ }
78159 }
79160
80161 pub proof fn get_arc_points_to( tracked self ) -> ( tracked ret: ArcPointsTo <T >)
@@ -83,11 +164,57 @@ impl<T> SmartPtrPointsTo<T> {
83164 returns
84165 self ->Arc_0 ,
85166 {
86- let tracked option_perm = match self {
87- SmartPtrPointsTo :: Arc ( p) => Some ( p) ,
88- _ => None ,
167+ match self {
168+ SmartPtrPointsTo :: Arc ( p) => p,
169+ _ => proof_from_false( ) ,
170+ }
171+ }
172+
173+ pub proof fn new_box_points_to(
174+ tracked points_to: PointsTo <T >,
175+ tracked dealloc: Option <Dealloc >,
176+ ) -> ( tracked ret: SmartPtrPointsTo <T >)
177+ requires
178+ points_to. is_init( ) ,
179+ match dealloc {
180+ Some ( dealloc) => {
181+ &&& vstd:: layout:: size_of:: <T >( ) > 0
182+ &&& valid_layout( size_of:: <T >( ) , dealloc. align( ) as usize )
183+ &&& points_to. ptr( ) . addr( ) == dealloc. addr( )
184+ &&& points_to. ptr( ) @. provenance == dealloc. provenance( )
185+ &&& dealloc. size( ) == vstd:: layout:: size_of:: <T >( )
186+ &&& dealloc. align( ) == vstd:: layout:: align_of:: <T >( )
187+ } ,
188+ None => { vstd:: layout:: size_of:: <T >( ) == 0 } ,
189+ } ,
190+ ensures
191+ ret. inv( ) ,
192+ ret is Box ,
193+ returns
194+ ( SmartPtrPointsTo :: Box (
195+ BoxPointsTo { perm: PointsTowithDealloc { points_to, dealloc } } ,
196+ ) ) ,
197+ {
198+ let tracked box_points_to = BoxPointsTo {
199+ perm: PointsTowithDealloc :: new( points_to, dealloc) ,
89200 } ;
90- option_perm. tracked_unwrap( )
201+ SmartPtrPointsTo :: Box ( box_points_to)
202+ }
203+
204+ pub proof fn new_arc_points_to( tracked points_to: & ' static PointsTo <T >) -> ( tracked ret:
205+ SmartPtrPointsTo <T >)
206+ requires
207+ points_to. is_init( ) ,
208+ points_to. ptr( ) . addr( ) != 0 ,
209+ points_to. ptr( ) . addr( ) as int % vstd:: layout:: align_of:: <T >( ) as int == 0 ,
210+ ensures
211+ ret. inv( ) ,
212+ ret is Arc ,
213+ returns
214+ ( SmartPtrPointsTo :: Arc ( ArcPointsTo { perm: points_to } ) ) ,
215+ {
216+ let tracked arc_points_to = ArcPointsTo { perm: points_to } ;
217+ SmartPtrPointsTo :: Arc ( arc_points_to)
91218 }
92219}
93220
0 commit comments