1+ use safety:: { ensures, requires} ;
12use crate :: fmt;
23use crate :: marker:: { PhantomData , Unsize } ;
34use crate :: ops:: { CoerceUnsized , DispatchFromDyn } ;
45use crate :: ptr:: NonNull ;
56
7+ #[ cfg( kani) ]
8+ use crate :: kani;
9+
610/// A wrapper around a raw non-null `*mut T` that indicates that the possessor
711/// of this wrapper owns the referent. Useful for building abstractions like
812/// `Box<T>`, `Vec<T>`, `String`, and `HashMap<K, V>`.
@@ -84,13 +88,17 @@ impl<T: ?Sized> Unique<T> {
8488 ///
8589 /// `ptr` must be non-null.
8690 #[ inline]
91+ #[ requires( !ptr. is_null( ) ) ]
92+ #[ ensures( |result| result. as_ptr( ) == ptr) ]
8793 pub const unsafe fn new_unchecked ( ptr : * mut T ) -> Self {
8894 // SAFETY: the caller must guarantee that `ptr` is non-null.
8995 unsafe { Unique { pointer : NonNull :: new_unchecked ( ptr) , _marker : PhantomData } }
9096 }
9197
9298 /// Creates a new `Unique` if `ptr` is non-null.
9399 #[ inline]
100+ #[ ensures( |result| result. is_none( ) == ptr. is_null( ) ) ]
101+ #[ ensures( |result| result. is_none( ) || result. unwrap( ) . as_ptr( ) == ptr) ]
94102 pub const fn new ( ptr : * mut T ) -> Option < Self > {
95103 if let Some ( pointer) = NonNull :: new ( ptr) {
96104 Some ( Unique { pointer, _marker : PhantomData } )
@@ -102,13 +110,15 @@ impl<T: ?Sized> Unique<T> {
102110 /// Acquires the underlying `*mut` pointer.
103111 #[ must_use = "`self` will be dropped if the result is not used" ]
104112 #[ inline]
113+ #[ ensures( |result| !result. is_null( ) ) ]
105114 pub const fn as_ptr ( self ) -> * mut T {
106115 self . pointer . as_ptr ( )
107116 }
108117
109118 /// Acquires the underlying `*mut` pointer.
110119 #[ must_use = "`self` will be dropped if the result is not used" ]
111120 #[ inline]
121+ #[ ensures( |result| result. as_ptr( ) == self . pointer. as_ptr( ) ) ]
112122 pub const fn as_non_null_ptr ( self ) -> NonNull < T > {
113123 self . pointer
114124 }
@@ -201,3 +211,82 @@ impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
201211 Unique { pointer, _marker : PhantomData }
202212 }
203213}
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