@@ -112,6 +112,7 @@ impl<T: Sized> NonNull<T> {
112
112
#[ rustc_const_stable( feature = "const_nonnull_dangling" , since = "1.36.0" ) ]
113
113
#[ must_use]
114
114
#[ inline]
115
+ #[ ensures( |result| !result. pointer. is_null( ) && result. pointer. is_aligned( ) ) ]
115
116
pub const fn dangling ( ) -> Self {
116
117
// SAFETY: ptr::dangling_mut() returns a non-null well-aligned pointer.
117
118
unsafe {
@@ -269,6 +270,7 @@ impl<T: ?Sized> NonNull<T> {
269
270
#[ unstable( feature = "ptr_metadata" , issue = "81513" ) ]
270
271
#[ rustc_const_unstable( feature = "ptr_metadata" , issue = "81513" ) ]
271
272
#[ inline]
273
+ #[ ensures( |result| !result. pointer. is_null( ) ) ]
272
274
pub const fn from_raw_parts (
273
275
data_pointer : NonNull < ( ) > ,
274
276
metadata : <T as super :: Pointee >:: Metadata ,
@@ -287,6 +289,8 @@ impl<T: ?Sized> NonNull<T> {
287
289
#[ must_use = "this returns the result of the operation, \
288
290
without modifying the original"]
289
291
#[ 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 ( ) ) ]
290
294
pub const fn to_raw_parts ( self ) -> ( NonNull < ( ) > , <T as super :: Pointee >:: Metadata ) {
291
295
( self . cast ( ) , super :: metadata ( self . as_ptr ( ) ) )
292
296
}
@@ -1536,6 +1540,9 @@ impl<T> NonNull<[T]> {
1536
1540
#[ rustc_const_stable( feature = "const_slice_from_raw_parts_mut" , since = "1.83.0" ) ]
1537
1541
#[ must_use]
1538
1542
#[ inline]
1543
+ #[ ensures( |result| !result. pointer. is_null( )
1544
+ && result. pointer as * const T == data. pointer
1545
+ && unsafe { result. as_ref( ) } . len( ) == len) ]
1539
1546
pub const fn slice_from_raw_parts ( data : NonNull < T > , len : usize ) -> Self {
1540
1547
// SAFETY: `data` is a `NonNull` pointer which is necessarily non-null
1541
1548
unsafe { Self :: new_unchecked ( super :: slice_from_raw_parts_mut ( data. as_ptr ( ) , len) ) }
@@ -1884,6 +1891,20 @@ mod verify {
1884
1891
use crate :: ptr:: null_mut;
1885
1892
use kani:: PointerGenerator ;
1886
1893
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
+
1887
1908
impl < T > kani:: Arbitrary for NonNull < T > {
1888
1909
fn any ( ) -> Self {
1889
1910
let ptr: * mut T = kani:: any :: < usize > ( ) as * mut T ;
@@ -2035,6 +2056,115 @@ mod verify {
2035
2056
let offset = nonnull_xptr. align_offset ( invalid_align) ;
2036
2057
}
2037
2058
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
+
2038
2168
#[ kani:: proof_for_contract( NonNull :: as_mut) ]
2039
2169
pub fn non_null_check_as_mut ( ) {
2040
2170
let mut x: i32 = kani:: any ( ) ;
0 commit comments