Testing drop implementation from "Entirely Too Many Linked Lists"

I currently do the doubly-linked list from the book and have decided to write a test for its drop implementation using the crate testdrop.
However, I am facing some difficulties I would consider... weird.

I don't think the impl List for the list matters for this question, only how the Drop trait is implemented:


impl<T> Drop for List<T> {
    fn drop(&mut self) {
        while self.pop_front().is_some() {}
    }
}

and the test

    #[test]
    fn test_list_drop() {
        let testdrop = TestDrop::new();
        let list = &mut List::new();
        list.push_front(testdrop.new_item());
        list.push_front(testdrop.new_item());
        list.push_front(testdrop.new_item());
        list.push_back(testdrop.new_item());
        list.push_back(testdrop.new_item());
        list.push_back(testdrop.new_item());
        assert_eq!(6, testdrop.num_tracked_items());
        drop(list);
        assert_eq!(6, testdrop.num_dropped_items());
    }

running with assertion error:

---- fourth::test::test_list_drop stdout ----
thread 'fourth::test::test_list_drop' panicked at 'assertion failed: `(left == right)`
  left: `6`,
 right: `0`', src/fourth.rs:171:9

This is potentially a problem with my pop_front() implementation, however, when I copy my drop implementation directly from the code and use it, the test does pass:

    #[test]
    fn test_list_drop() {
        let testdrop = TestDrop::new();
        let list = &mut List::new();
        list.push_front(testdrop.new_item());
        list.push_front(testdrop.new_item());
        list.push_front(testdrop.new_item());
        list.push_back(testdrop.new_item());
        list.push_back(testdrop.new_item());
        list.push_back(testdrop.new_item());
        assert_eq!(6, testdrop.num_tracked_items());
        // drop(list);
        while list.pop_front().is_some() {}
        assert_eq!(6, testdrop.num_dropped_items());
    }

I have also added to my drop implementation a print statement to the while loop to make sure the code is indeed exectuted on drop(list) and it was printed 6 times as expected.

What am I missing?

Look closer at this code.

let list = &mut List::new();

What this code actually do is to create a list and store it at some hidden variable, and take a &mut of it and assign it to the variable list. The variable will be dropped at the end of the block as usual, and dropping the &mut List is effectively no-op.

2 Likes

Oh I get it, changed it to

let mut list = List::new()

and it worked.
Thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.