Iterators and Drop

Implement Iterator three ways, and fix the stack overflow on drop.

Part 2 of 3Updated

A long list overflows the stack when dropped: each Node’s destructor drops the next one recursively. Write it out iteratively:

impl<T> Drop for List<T> {
    fn drop(&mut self) {
        let mut cur = self.head.take();
        while let Some(mut node) = cur {
            cur = node.next.take();
        }
    }
}

Then three iterators, which is really three ways of expressing ownership:

Type Yields Consumes the list?
IntoIter T yes
Iter<'a> &'a T no
IterMut<'a> &'a mut T no

IterMut is the one that surprises people β€” it’s safe, but only because the borrow checker can prove you never hand out two &mut to the same node.