@@ -112,6 +112,7 @@ impl<T: Sized> NonNull<T> {
112112 #[ rustc_const_stable( feature = "const_nonnull_dangling" , since = "1.36.0" ) ]
113113 #[ must_use]
114114 #[ inline]
115+ #[ ensures( |result| !result. pointer. is_null( ) && result. pointer. is_aligned( ) ) ]
115116 pub const fn dangling ( ) -> Self {
116117 // SAFETY: ptr::dangling_mut() returns a non-null well-aligned pointer.
117118 unsafe {
@@ -269,6 +270,7 @@ impl<T: ?Sized> NonNull<T> {
269270 #[ unstable( feature = "ptr_metadata" , issue = "81513" ) ]
270271 #[ rustc_const_unstable( feature = "ptr_metadata" , issue = "81513" ) ]
271272 #[ inline]
273+ #[ ensures( |result| !result. pointer. is_null( ) ) ]
272274 pub const fn from_raw_parts (
273275 data_pointer : NonNull < ( ) > ,
274276 metadata : <T as super :: Pointee >:: Metadata ,
@@ -287,6 +289,8 @@ impl<T: ?Sized> NonNull<T> {
287289 #[ must_use = "this returns the result of the operation, \
288290 without modifying the original"]
289291 #[ inline]
292+ #[ ensures( |( data_ptr, metadata) | !data_ptr. as_ptr( ) . is_null( ) ) ]
293+ #[ ensures( |( data_ptr, metadata) | self . as_ptr( ) as * const ( ) == data_ptr. as_ptr( ) as * const ( ) ) ]
290294 pub const fn to_raw_parts ( self ) -> ( NonNull < ( ) > , <T as super :: Pointee >:: Metadata ) {
291295 ( self . cast ( ) , super :: metadata ( self . as_ptr ( ) ) )
292296 }
@@ -1536,6 +1540,9 @@ impl<T> NonNull<[T]> {
15361540 #[ rustc_const_stable( feature = "const_slice_from_raw_parts_mut" , since = "1.83.0" ) ]
15371541 #[ must_use]
15381542 #[ inline]
1543+ #[ ensures( |result| !result. pointer. is_null( )
1544+ && result. pointer as * const T == data. pointer
1545+ && unsafe { result. as_ref( ) } . len( ) == len) ]
15391546 pub const fn slice_from_raw_parts ( data : NonNull < T > , len : usize ) -> Self {
15401547 // SAFETY: `data` is a `NonNull` pointer which is necessarily non-null
15411548 unsafe { Self :: new_unchecked ( super :: slice_from_raw_parts_mut ( data. as_ptr ( ) , len) ) }
@@ -1884,6 +1891,20 @@ mod verify {
18841891 use crate :: ptr:: null_mut;
18851892 use kani:: PointerGenerator ;
18861893
1894+ trait SampleTrait {
1895+ fn get_value ( & self ) -> i32 ;
1896+ }
1897+
1898+ struct SampleStruct {
1899+ value : i32 ,
1900+ }
1901+
1902+ impl SampleTrait for SampleStruct {
1903+ fn get_value ( & self ) -> i32 {
1904+ self . value
1905+ }
1906+ }
1907+
18871908 impl < T > kani:: Arbitrary for NonNull < T > {
18881909 fn any ( ) -> Self {
18891910 let ptr: * mut T = kani:: any :: < usize > ( ) as * mut T ;
@@ -2035,6 +2056,115 @@ mod verify {
20352056 let offset = nonnull_xptr. align_offset ( invalid_align) ;
20362057 }
20372058
2059+ // pub const fn dangling() -> Self
2060+ #[ kani:: proof_for_contract( NonNull :: dangling) ]
2061+ pub fn non_null_check_dangling ( ) {
2062+ // unsigned integer types
2063+ let ptr_u8 = NonNull :: < u8 > :: dangling ( ) ;
2064+ let ptr_u16 = NonNull :: < u16 > :: dangling ( ) ;
2065+ let ptr_u32 = NonNull :: < u32 > :: dangling ( ) ;
2066+ let ptr_u64 = NonNull :: < u64 > :: dangling ( ) ;
2067+ let ptr_u128 = NonNull :: < u128 > :: dangling ( ) ;
2068+ let ptr_usize = NonNull :: < usize > :: dangling ( ) ;
2069+ // signed integer types
2070+ let ptr_i8 = NonNull :: < i8 > :: dangling ( ) ;
2071+ let ptr_i16 = NonNull :: < i16 > :: dangling ( ) ;
2072+ let ptr_i32 = NonNull :: < i32 > :: dangling ( ) ;
2073+ let ptr_i64 = NonNull :: < i64 > :: dangling ( ) ;
2074+ let ptr_i128 = NonNull :: < i128 > :: dangling ( ) ;
2075+ let ptr_isize = NonNull :: < isize > :: dangling ( ) ;
2076+ // unit type
2077+ let ptr_unit = NonNull :: < ( ) > :: dangling ( ) ;
2078+ // zero length slice from dangling unit pointer
2079+ let zero_len_slice = NonNull :: slice_from_raw_parts ( ptr_unit, 0 ) ;
2080+ }
2081+
2082+ // pub const fn from_raw_parts(data_pointer: NonNull<()>, metadata: <T as super::Pointee>::Metadata,) -> NonNull<T>
2083+ #[ kani:: proof_for_contract( NonNull :: from_raw_parts) ]
2084+ #[ kani:: unwind( 101 ) ]
2085+ pub fn non_null_check_from_raw_parts ( ) {
2086+ const ARR_LEN : usize = 100 ;
2087+ // Create a non-deterministic array and its slice
2088+ let arr: [ i8 ; ARR_LEN ] = kani:: any ( ) ;
2089+ let arr_slice = kani:: slice:: any_slice_of_array ( & arr) ;
2090+ // Get a raw NonNull pointer to the start of the slice
2091+ let arr_slice_raw_ptr = NonNull :: new ( arr_slice. as_ptr ( ) as * mut ( ) ) . unwrap ( ) ;
2092+ // Create NonNull pointer from the start pointer and the length of the slice
2093+ let nonnull_slice = NonNull :: < [ i8 ] > :: from_raw_parts ( arr_slice_raw_ptr, arr_slice. len ( ) ) ;
2094+ // Ensure slice content is preserved, runtime at this step is proportional to ARR_LEN
2095+ unsafe {
2096+ kani:: assert ( arr_slice == nonnull_slice. as_ref ( ) , "slice content must be preserve" ) ;
2097+ }
2098+
2099+ // zero-length dangling pointer example
2100+ let dangling_ptr = NonNull :: < ( ) > :: dangling ( ) ;
2101+ let zero_length = NonNull :: < [ ( ) ] > :: from_raw_parts ( dangling_ptr, 0 ) ;
2102+ }
2103+
2104+ #[ kani:: proof_for_contract( NonNull :: from_raw_parts) ]
2105+ pub fn non_null_check_from_raw_part_trait ( ) {
2106+ // Create a SampleTrait object from SampleStruct
2107+ let sample_struct = SampleStruct { value : kani:: any ( ) } ;
2108+ let trait_object: & dyn SampleTrait = & sample_struct;
2109+
2110+ // Get the raw data pointer and metadata for the trait object
2111+ let trait_ptr = NonNull :: new ( trait_object as * const dyn SampleTrait as * mut ( ) ) . unwrap ( ) ;
2112+ // Safety: For trait objects, the metadata must come from a pointer to the same underlying erased type
2113+ let metadata = core:: ptr:: metadata ( trait_object) ;
2114+
2115+ // Create NonNull<dyn MyTrait> from the data pointer and metadata
2116+ let nonnull_trait_object: NonNull < dyn SampleTrait > = NonNull :: from_raw_parts ( trait_ptr, metadata) ;
2117+
2118+ unsafe {
2119+ // Ensure trait method and member is preserved
2120+ kani:: assert ( trait_object. get_value ( ) == nonnull_trait_object. as_ref ( ) . get_value ( ) , "trait method and member must correctly preserve" ) ;
2121+ }
2122+ }
2123+
2124+ // pub const fn slice_from_raw_parts(data: NonNull<T>, len: usize) -> Self
2125+ #[ kani:: proof_for_contract( NonNull :: slice_from_raw_parts) ]
2126+ #[ kani:: unwind( 1001 ) ]
2127+ pub fn non_null_check_slice_from_raw_parts ( ) {
2128+ const ARR_LEN : usize = 1000 ;
2129+ // Create a non-deterministic array
2130+ let mut arr: [ i8 ; ARR_LEN ] = kani:: any ( ) ;
2131+ // Get a raw NonNull pointer to the start of the slice
2132+ let arr_raw_ptr = NonNull :: new ( arr. as_mut_ptr ( ) ) . unwrap ( ) ;
2133+ // Create NonNull slice from the start pointer and ends at random slice_len
2134+ // Safety: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html
2135+ let slice_len: usize = kani:: any ( ) ;
2136+ kani:: assume ( slice_len <= ARR_LEN ) ;
2137+ let nonnull_slice = NonNull :: < [ i8 ] > :: slice_from_raw_parts ( arr_raw_ptr, slice_len) ;
2138+ // Ensure slice content is preserved, runtime at this step is proportional to ARR_LEN
2139+ unsafe {
2140+ kani:: assert ( & arr[ ..slice_len] == nonnull_slice. as_ref ( ) , "slice content must be preserve" ) ;
2141+ }
2142+
2143+ // TODO: zero-length example blocked by kani issue [#3670](https://github.com/model-checking/kani/issues/3670)
2144+ //let dangling_ptr = NonNull::<()>::dangling();
2145+ //let zero_length = NonNull::<[()]>::slice_from_raw_parts(dangling_ptr, 0);
2146+ }
2147+
2148+
2149+ // pub const fn to_raw_parts(self) -> (NonNull<()>, <T as super::Pointee>::Metadata)
2150+ #[ kani:: proof_for_contract( NonNull :: to_raw_parts) ]
2151+ pub fn non_null_check_to_raw_parts ( ) {
2152+ // Create a SampleTrait object from SampleStruct
2153+ let sample_struct = SampleStruct { value : kani:: any ( ) } ;
2154+ let trait_object: & dyn SampleTrait = & sample_struct;
2155+
2156+ // Get the raw data pointer and metadata for the trait object
2157+ let trait_ptr = NonNull :: from ( trait_object) . cast :: < ( ) > ( ) ; //both have eq failure
2158+ //let trait_ptr = NonNull::new(trait_object as *const dyn SampleTrait as *mut ()).unwrap(); //Question: what's the difference
2159+ // Safety: For trait objects, the metadata must come from a pointer to the same underlying erased type
2160+ let metadata = core:: ptr:: metadata ( trait_object) ;
2161+
2162+ // Create NonNull<dyn MyTrait> from the data pointer and metadata
2163+ let nonnull_trait_object: NonNull < dyn SampleTrait > = NonNull :: from_raw_parts ( trait_ptr, metadata) ;
2164+ let ( decomposed_data_ptr, decomposed_metadata) = NonNull :: to_raw_parts ( nonnull_trait_object) ;
2165+ }
2166+
2167+
20382168 #[ kani:: proof_for_contract( NonNull :: as_mut) ]
20392169 pub fn non_null_check_as_mut ( ) {
20402170 let mut x: i32 = kani:: any ( ) ;
0 commit comments