Iterator lifetime error only when using a mutable reference

The Iterator interface promises that this is always valid code:

let a = iter.next().unwrap();
let b = iter.next().unwrap();
drop(iter);
use_both(a, b);

Your iterator returns exclusive reference self.r twice, which means you can get a and b existing at the same time and both claim to be the only way access to whatever self.r referenced. That's a logical contradiction, so it can't be allowed.

Second problem is that even if your code was technically correct (e.g. you set a flag or used split_at_mut() to ensure you never return same reference twice), the lifetimes aren't precise enough to express that. The borrow checker doesn't look at what the code actually does, only at what it declares via type annotations.

So in practice it means all mutable iterators in Rust have to use unsafe (or reuse an existing mutable iterator that is going to have unsafe in it) to overcome that limitation of the borrow checker, and the programmer is responsible for ensuring that exclusive references remain exclusive.

3 Likes