1
+ use safety:: { ensures, requires} ;
1
2
use crate :: fmt;
2
3
use crate :: marker:: { PhantomData , Unsize } ;
3
4
use crate :: ops:: { CoerceUnsized , DispatchFromDyn } ;
4
5
use crate :: ptr:: NonNull ;
5
6
7
+ #[ cfg( kani) ]
8
+ use crate :: kani;
9
+
6
10
/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
7
11
/// of this wrapper owns the referent. Useful for building abstractions like
8
12
/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
@@ -84,13 +88,17 @@ impl<T: ?Sized> Unique<T> {
84
88
///
85
89
/// `ptr` must be non-null.
86
90
#[ inline]
91
+ #[ requires( !ptr. is_null( ) ) ]
92
+ #[ ensures( |result| result. as_ptr( ) == ptr) ]
87
93
pub const unsafe fn new_unchecked ( ptr : * mut T ) -> Self {
88
94
// SAFETY: the caller must guarantee that `ptr` is non-null.
89
95
unsafe { Unique { pointer : NonNull :: new_unchecked ( ptr) , _marker : PhantomData } }
90
96
}
91
97
92
98
/// Creates a new `Unique` if `ptr` is non-null.
93
99
#[ inline]
100
+ #[ ensures( |result| result. is_none( ) == ptr. is_null( ) ) ]
101
+ #[ ensures( |result| result. is_none( ) || result. unwrap( ) . as_ptr( ) == ptr) ]
94
102
pub const fn new ( ptr : * mut T ) -> Option < Self > {
95
103
if let Some ( pointer) = NonNull :: new ( ptr) {
96
104
Some ( Unique { pointer, _marker : PhantomData } )
@@ -102,13 +110,15 @@ impl<T: ?Sized> Unique<T> {
102
110
/// Acquires the underlying `*mut` pointer.
103
111
#[ must_use = "`self` will be dropped if the result is not used" ]
104
112
#[ inline]
113
+ #[ ensures( |result| !result. is_null( ) ) ]
105
114
pub const fn as_ptr ( self ) -> * mut T {
106
115
self . pointer . as_ptr ( )
107
116
}
108
117
109
118
/// Acquires the underlying `*mut` pointer.
110
119
#[ must_use = "`self` will be dropped if the result is not used" ]
111
120
#[ inline]
121
+ #[ ensures( |result| result. as_ptr( ) == self . pointer. as_ptr( ) ) ]
112
122
pub const fn as_non_null_ptr ( self ) -> NonNull < T > {
113
123
self . pointer
114
124
}
@@ -201,3 +211,82 @@ impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
201
211
Unique { pointer, _marker : PhantomData }
202
212
}
203
213
}
214
+
215
+ #[ cfg( kani) ]
216
+ #[ unstable( feature="kani" , issue="none" ) ]
217
+ mod verify {
218
+ use super :: * ;
219
+
220
+ // pub const unsafe fn new_unchecked(ptr: *mut T) -> Self
221
+ #[ kani:: proof_for_contract( Unique :: new_unchecked) ]
222
+ pub fn check_new_unchecked ( ) {
223
+ let mut x : i32 = kani:: any ( ) ;
224
+ let xptr = & mut x;
225
+ unsafe {
226
+ let _ = Unique :: new_unchecked ( xptr as * mut i32 ) ;
227
+ }
228
+ }
229
+
230
+ // pub const fn new(ptr: *mut T) -> Option<Self>
231
+ #[ kani:: proof_for_contract( Unique :: new) ]
232
+ pub fn check_new ( ) {
233
+ let mut x : i32 = kani:: any ( ) ;
234
+ let xptr = & mut x;
235
+ let _ = Unique :: new ( xptr as * mut i32 ) ;
236
+ }
237
+
238
+ // pub const fn as_ptr(self) -> *mut T
239
+ #[ kani:: proof_for_contract( Unique :: as_ptr) ]
240
+ pub fn check_as_ptr ( ) {
241
+ let mut x : i32 = kani:: any ( ) ;
242
+ let xptr = & mut x;
243
+ unsafe {
244
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
245
+ assert_eq ! ( unique. as_ptr( ) , xptr as * mut i32 ) ;
246
+ }
247
+ }
248
+
249
+ // pub const fn as_non_null_ptr(self) -> NonNull<T>
250
+ #[ kani:: proof_for_contract( Unique :: as_non_null_ptr) ]
251
+ pub fn check_as_non_null_ptr ( ) {
252
+ let mut x : i32 = kani:: any ( ) ;
253
+ let xptr = & mut x;
254
+ unsafe {
255
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
256
+ let _ = unique. as_non_null_ptr ( ) ;
257
+ }
258
+ }
259
+
260
+ // pub const unsafe fn as_ref(&self) -> &T
261
+ #[ kani:: proof]
262
+ pub fn check_as_ref ( ) {
263
+ let mut x : i32 = kani:: any ( ) ;
264
+ let xptr = & mut x;
265
+ unsafe {
266
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
267
+ assert_eq ! ( * unique. as_ref( ) , x) ;
268
+ }
269
+ }
270
+
271
+ // pub const unsafe fn as_mut(&mut self) -> &mut T
272
+ #[ kani:: proof]
273
+ pub fn check_as_mut ( ) {
274
+ let mut x : i32 = kani:: any ( ) ;
275
+ let xptr = & mut x;
276
+ unsafe {
277
+ let mut unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
278
+ assert_eq ! ( * unique. as_mut( ) , x) ;
279
+ }
280
+ }
281
+
282
+ // pub const fn cast<U>(self) -> Unique<U>
283
+ #[ kani:: proof_for_contract( Unique :: cast<U >) ]
284
+ pub fn check_cast < U > ( ) {
285
+ let mut x : i32 = kani:: any ( ) ;
286
+ let xptr = & mut x;
287
+ unsafe {
288
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
289
+ assert_eq ! ( * unique. cast:: <u32 >( ) . as_ref( ) , x as u32 ) ;
290
+ }
291
+ }
292
+ }
0 commit comments