Learn Rust With Entirely Too Many Linked Lists
47

Testing Cursors

Cursor tests stress two things: that movement composes correctly across the ghost boundary, and that insert/remove/splice leave the structure consistent. Run them under Miri — cursors are where pointer logic gets hairiest, and a wrong rewire that doesn't crash the test will still trip aliasing checks.

  1. Round-trip test: walk the list to the back, walk back to the front, and compare to the original. Splice test: build two lists, splice one into the other at a known position, verify the resulting sequence.
    #[cfg(test)]
    mod cursor_tests {
        use super::*;
    
        #[test]
        fn walk_and_return() {
            let mut l: LinkedList<i32> = (0..5).collect();
            let mut c = l.cursor_mut();
            c.move_next();
            for _ in 0..5 { c.move_next(); }
            assert!(c.current().is_none()); // ghost
            c.move_next();
            assert_eq!(c.current(), Some(&mut 0));
        }
    
        #[test]
        fn splice_into_middle() {
            let mut a: LinkedList<i32> = vec![1, 2, 5, 6].into_iter().collect();
            let b: LinkedList<i32> = vec![3, 4].into_iter().collect();
            let mut c = a.cursor_mut();
            c.move_next(); c.move_next(); c.move_next(); // at 2
            c.move_next(); // at 5
            c.splice_before(b);
            let v: Vec<i32> = a.into_iter().collect();
            assert_eq!(v, vec![1, 2, 3, 4, 5, 6]);
        }
    }
  2. Run the cursor tests under Miri the same way as the basic tests. Anything that touches multiple raw pointers in close succession is the most likely place to find aliasing violations.
    $ cargo +nightly miri test cursor
    running 2 tests
    test sixth::cursor_tests::walk_and_return ... ok
    test sixth::cursor_tests::splice_into_middle ... ok
    
    test result: ok. 2 passed; 0 failed