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,16 @@ impl<T: ?Sized> Unique<T> {
84
88
///
85
89
/// `ptr` must be non-null.
86
90
#[ inline]
91
+ #[ requires( !ptr. is_null( ) ) ]
87
92
pub const unsafe fn new_unchecked ( ptr : * mut T ) -> Self {
88
93
// SAFETY: the caller must guarantee that `ptr` is non-null.
89
94
unsafe { Unique { pointer : NonNull :: new_unchecked ( ptr) , _marker : PhantomData } }
90
95
}
91
96
92
97
/// Creates a new `Unique` if `ptr` is non-null.
93
98
#[ inline]
99
+ #[ ensures( |result| result. is_none( ) == result. unwrap( ) . as_ptr( ) . is_null( ) ) ]
100
+ #[ ensures( |result| result. is_none( ) || result. unwrap( ) . as_ptr( ) == ptr) ]
94
101
pub const fn new ( ptr : * mut T ) -> Option < Self > {
95
102
if let Some ( pointer) = NonNull :: new ( ptr) {
96
103
Some ( Unique { pointer, _marker : PhantomData } )
@@ -102,6 +109,7 @@ impl<T: ?Sized> Unique<T> {
102
109
/// Acquires the underlying `*mut` pointer.
103
110
#[ must_use = "`self` will be dropped if the result is not used" ]
104
111
#[ inline]
112
+ #[ ensures( |result| !result. is_null( ) ) ]
105
113
pub const fn as_ptr ( self ) -> * mut T {
106
114
self . pointer . as_ptr ( )
107
115
}
@@ -201,3 +209,92 @@ impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
201
209
Unique { pointer, _marker : PhantomData }
202
210
}
203
211
}
212
+
213
+ #[ cfg( kani) ]
214
+ #[ unstable( feature="kani" , issue="none" ) ]
215
+ mod verify {
216
+ use super :: * ;
217
+
218
+ // pub const unsafe fn new_unchecked(ptr: *mut T) -> Self
219
+ #[ kani:: proof_for_contract( Unique :: new_unchecked) ]
220
+ pub fn check_new_unchecked ( ) {
221
+ let mut x : i32 = 42 ;
222
+ let xptr = & mut x;
223
+
224
+ unsafe {
225
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
226
+ assert_eq ! ( unique. as_ptr( ) , 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 = 42 ;
234
+ let xptr = & mut x;
235
+
236
+ if let Some ( unique) = Unique :: new ( xptr as * mut i32 ) {
237
+ assert_eq ! ( unique. as_ptr( ) , xptr as * mut i32 ) ;
238
+ }
239
+ }
240
+
241
+ // pub const fn as_ptr(self) -> *mut T
242
+ #[ kani:: proof_for_contract( Unique :: as_ptr) ]
243
+ pub fn check_as_ptr ( ) {
244
+ let mut x : i32 = 42 ;
245
+ let xptr = & mut x;
246
+
247
+ unsafe {
248
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
249
+ assert_eq ! ( unique. as_ptr( ) , xptr as * mut i32 ) ;
250
+ }
251
+ }
252
+
253
+ // pub const fn as_non_null_ptr(self) -> NonNull<T>
254
+ #[ kani:: proof]
255
+ pub fn check_as_non_null_ptr ( ) {
256
+ let mut x : i32 = 42 ;
257
+ let xptr = & mut x;
258
+
259
+ unsafe {
260
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
261
+ assert_eq ! ( unique. as_non_null_ptr( ) . as_ptr( ) , xptr as * mut i32 ) ;
262
+ }
263
+ }
264
+
265
+ // pub const unsafe fn as_ref(&self) -> &T
266
+ #[ kani:: proof]
267
+ pub fn check_as_ref ( ) {
268
+ let mut x : i32 = 42 ;
269
+ let xptr = & mut x;
270
+
271
+ unsafe {
272
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
273
+ assert_eq ! ( * unique. as_ref( ) , x) ;
274
+ }
275
+ }
276
+
277
+ // pub const unsafe fn as_mut(&mut self) -> &mut T
278
+ #[ kani:: proof]
279
+ pub fn check_as_mut ( ) {
280
+ let mut x : i32 = 42 ;
281
+ let xptr = & mut x;
282
+
283
+ unsafe {
284
+ let mut unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
285
+ assert_eq ! ( * unique. as_mut( ) , x) ;
286
+ }
287
+ }
288
+
289
+ // pub const fn cast<U>(self) -> Unique<U>
290
+ #[ kani:: proof_for_contract( Unique :: cast<U >) ]
291
+ pub fn check_cast < U > ( ) {
292
+ let mut x : i32 = 42 ;
293
+ let xptr = & mut x;
294
+
295
+ unsafe {
296
+ let unique = Unique :: new_unchecked ( xptr as * mut i32 ) ;
297
+ assert_eq ! ( * unique. cast:: <u32 >( ) . as_ref( ) , x as u32 ) ;
298
+ }
299
+ }
300
+ }
0 commit comments