1010//! [`Vec`]: crate::vec::Vec
1111//! [`VecDeque`]: super::vec_deque::VecDeque
1212
13+ #![ feature( ub_checks) ]
1314#![ stable( feature = "rust1" , since = "1.0.0" ) ]
1415
16+ use safety:: { ensures, requires} ;
17+ #[ cfg( kani) ]
18+ #[ unstable( feature="kani" , issue="none" ) ]
19+ use core:: kani;
20+ #[ allow( unused_imports) ]
21+ #[ unstable( feature = "ub_checks" , issue = "none" ) ]
22+ use core:: ub_checks:: * ;
23+
1524use core:: cmp:: Ordering ;
1625use core:: hash:: { Hash , Hasher } ;
1726use core:: iter:: FusedIterator ;
@@ -170,6 +179,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
170179 /// `node` must point to a valid node that was boxed and leaked using the list's allocator.
171180 /// This method takes ownership of the node, so the pointer should not be used again.
172181 #[ inline]
182+ #[ requires( can_dereference( node. as_ptr( ) ) ) ]
173183 unsafe fn push_front_node ( & mut self , node : NonNull < Node < T > > ) {
174184 // This method takes care not to create mutable references to whole nodes,
175185 // to maintain validity of aliasing pointers into `element`.
@@ -215,6 +225,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
215225 /// `node` must point to a valid node that was boxed and leaked using the list's allocator.
216226 /// This method takes ownership of the node, so the pointer should not be used again.
217227 #[ inline]
228+ #[ requires( can_dereference( node. as_ptr( ) ) ) ]
218229 unsafe fn push_back_node ( & mut self , node : NonNull < Node < T > > ) {
219230 // This method takes care not to create mutable references to whole nodes,
220231 // to maintain validity of aliasing pointers into `element`.
@@ -261,6 +272,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
261272 /// This method takes care not to create mutable references to `element`, to
262273 /// maintain validity of aliasing pointers.
263274 #[ inline]
275+ #[ requires( can_dereference( node. as_ptr( ) ) ) ]
264276 unsafe fn unlink_node ( & mut self , mut node : NonNull < Node < T > > ) {
265277 let node = unsafe { node. as_mut ( ) } ; // this one is ours now, we can create an &mut.
266278
@@ -284,6 +296,10 @@ impl<T, A: Allocator> LinkedList<T, A> {
284296 ///
285297 /// Warning: this will not check that the provided node belongs to the two existing lists.
286298 #[ inline]
299+ #[ requires( can_dereference( splice_start. as_ptr( ) ) ) ]
300+ #[ requires( can_dereference( splice_end. as_ptr( ) ) ) ]
301+ #[ requires( existing_prev. map_or( true , |prev| can_dereference( prev. as_ptr( ) ) ) ) ]
302+ #[ requires( existing_next. map_or( true , |next| can_dereference( next. as_ptr( ) ) ) ) ]
287303 unsafe fn splice_nodes (
288304 & mut self ,
289305 existing_prev : Option < NonNull < Node < T > > > ,
@@ -318,6 +334,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
318334
319335 /// Detaches all nodes from a linked list as a series of nodes.
320336 #[ inline]
337+ #[ requires( self . head. is_some( ) ) ]
321338 fn detach_all_nodes ( mut self ) -> Option < ( NonNull < Node < T > > , NonNull < Node < T > > , usize ) > {
322339 let head = self . head . take ( ) ;
323340 let tail = self . tail . take ( ) ;
@@ -334,6 +351,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
334351 }
335352
336353 #[ inline]
354+ #[ requires( at <= self . len) ]
337355 unsafe fn split_off_before_node (
338356 & mut self ,
339357 split_node : Option < NonNull < Node < T > > > ,
@@ -377,6 +395,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
377395 }
378396
379397 #[ inline]
398+ #[ requires( at <= self . len) ]
380399 unsafe fn split_off_after_node (
381400 & mut self ,
382401 split_node : Option < NonNull < Node < T > > > ,
@@ -2205,3 +2224,177 @@ unsafe impl<T: Send, A: Allocator + Send> Send for CursorMut<'_, T, A> {}
22052224
22062225#[ unstable( feature = "linked_list_cursors" , issue = "58533" ) ]
22072226unsafe impl < T : Sync , A : Allocator + Sync > Sync for CursorMut < ' _ , T , A > { }
2227+ #[ cfg( kani) ]
2228+ mod verify {
2229+ use super :: * ;
2230+ #[ cfg( kani) ]
2231+ #[ kani:: proof_for_contract( LinkedList :: push_front_node) ]
2232+ fn proof_for_push_front_node ( ) {
2233+ // Create a new linked list
2234+ let mut list: LinkedList < i32 > = LinkedList :: new ( ) ;
2235+
2236+ // Create a new node with a value
2237+ let value = kani:: any :: < i32 > ( ) ;
2238+ let node_box = Box :: new ( Node :: new ( value) ) ;
2239+ let node_ptr = NonNull :: from ( Box :: leak ( node_box) ) ;
2240+
2241+ // Call the function with the valid node pointer
2242+ unsafe {
2243+ list. push_front_node ( node_ptr) ;
2244+ }
2245+ }
2246+
2247+ #[ cfg( kani) ]
2248+ #[ kani:: proof_for_contract( LinkedList :: push_back_node) ]
2249+ fn proof_for_push_back_node ( ) {
2250+ // Create a new linked list
2251+ let mut list: LinkedList < i32 > = LinkedList :: new ( ) ;
2252+
2253+ // Create a new node with a value
2254+ let value = kani:: any :: < i32 > ( ) ;
2255+ let node_box = Box :: new ( Node :: new ( value) ) ;
2256+ let node_ptr = NonNull :: from ( Box :: leak ( node_box) ) ;
2257+
2258+ // Call the function with the valid node pointer
2259+ unsafe {
2260+ list. push_back_node ( node_ptr) ;
2261+ }
2262+ }
2263+
2264+ #[ cfg( kani) ]
2265+ #[ kani:: proof_for_contract( LinkedList :: unlink_node) ]
2266+ fn proof_for_unlink_node ( ) {
2267+ // Create a new linked list with one element
2268+ let mut list: LinkedList < i32 > = LinkedList :: new ( ) ;
2269+
2270+ // Add a node to the list so we can unlink it
2271+ let value = kani:: any :: < i32 > ( ) ;
2272+ list. push_back ( value) ;
2273+
2274+ // Get the node pointer from the list
2275+ let node_ptr = list. head . unwrap ( ) ;
2276+
2277+ // Call the function with the valid node pointer
2278+ unsafe {
2279+ list. unlink_node ( node_ptr) ;
2280+ }
2281+ }
2282+
2283+ #[ cfg( kani) ]
2284+ #[ kani:: proof_for_contract( LinkedList :: splice_nodes) ]
2285+ fn proof_for_splice_nodes ( ) {
2286+ // Create two linked lists
2287+ let mut target_list: LinkedList < i32 > = LinkedList :: new ( ) ;
2288+ let mut source_list: LinkedList < i32 > = LinkedList :: new ( ) ;
2289+
2290+ // Add some elements to both lists
2291+ target_list. push_back ( 1 ) ;
2292+ target_list. push_back ( 2 ) ;
2293+
2294+ source_list. push_back ( 10 ) ;
2295+ source_list. push_back ( 20 ) ;
2296+
2297+ // Get pointers to nodes in the target list
2298+ let existing_prev = target_list. head ;
2299+ let existing_next = target_list. tail ;
2300+
2301+ // Get pointers to the start and end of the source list
2302+ let splice_start = source_list. head . unwrap ( ) ;
2303+ let splice_end = source_list. tail . unwrap ( ) ;
2304+ let splice_length = source_list. len ;
2305+
2306+ // Detach the nodes from source_list to avoid double-free
2307+ let _ = source_list. detach_all_nodes ( ) ;
2308+
2309+ // Call the function with the valid node pointers
2310+ unsafe {
2311+ target_list. splice_nodes (
2312+ existing_prev,
2313+ existing_next,
2314+ splice_start,
2315+ splice_end,
2316+ splice_length,
2317+ ) ;
2318+ }
2319+ }
2320+
2321+ #[ cfg( kani) ]
2322+ #[ kani:: proof_for_contract( LinkedList :: split_off_after_node) ]
2323+ fn proof_for_split_off_after_node ( ) {
2324+ // Create a linked list with a few elements
2325+ let mut list: LinkedList < i32 > = LinkedList :: new ( ) ;
2326+
2327+ // Add some elements to the list
2328+ list. push_back ( 1 ) ;
2329+ list. push_back ( 2 ) ;
2330+ list. push_back ( 3 ) ;
2331+
2332+ // Get the length of the list
2333+ let len = list. len ;
2334+
2335+ // Choose a valid split point that satisfies at <= self.len
2336+ let at = if len > 0 {
2337+ kani:: any :: < usize > ( ) % ( len + 1 )
2338+ } else {
2339+ 0
2340+ } ;
2341+
2342+ // For simplicity, use None as the split_node
2343+ // This is valid for the contract which only requires at <= self.len
2344+ let split_node = None ;
2345+
2346+ // Call the function with the valid parameters
2347+ unsafe {
2348+ let _second_part = list. split_off_after_node ( split_node, at) ;
2349+ }
2350+ }
2351+
2352+ #[ cfg( kani) ]
2353+ #[ kani:: proof_for_contract( LinkedList :: split_off_before_node) ]
2354+ fn proof_for_split_off_before_node ( ) {
2355+ // Create a linked list with a few elements
2356+ let mut list: LinkedList < i32 > = LinkedList :: new ( ) ;
2357+
2358+ // Add some elements to the list
2359+ list. push_back ( 1 ) ;
2360+ list. push_back ( 2 ) ;
2361+ list. push_back ( 3 ) ;
2362+
2363+ // Get the length of the list
2364+ let len = list. len ;
2365+
2366+ // Choose a valid split point that satisfies at <= self.len
2367+ let at = if len > 0 {
2368+ kani:: any :: < usize > ( ) % ( len + 1 )
2369+ } else {
2370+ 0
2371+ } ;
2372+
2373+ // For simplicity, use None as the split_node
2374+ // This is valid for the contract which only requires at <= self.len
2375+ let split_node = None ;
2376+
2377+ // Call the function with the valid parameters
2378+ unsafe {
2379+ let _first_part = list. split_off_before_node ( split_node, at) ;
2380+ }
2381+ }
2382+
2383+ #[ cfg( kani) ]
2384+ #[ kani:: proof_for_contract( LinkedList :: detach_all_nodes) ]
2385+ fn proof_for_detach_all_nodes ( ) {
2386+ // Create a linked list with at least one element to satisfy the precondition
2387+ let mut list: LinkedList < i32 > = LinkedList :: new ( ) ;
2388+
2389+ // Add an element to ensure self.head.is_some()
2390+ list. push_back ( kani:: any :: < i32 > ( ) ) ;
2391+
2392+ // Optionally add more elements
2393+ if kani:: any ( ) {
2394+ list. push_back ( kani:: any :: < i32 > ( ) ) ;
2395+ }
2396+
2397+ // Call the function
2398+ let _result = list. detach_all_nodes ( ) ;
2399+ }
2400+ }
0 commit comments