According to @kornel in When is transmuting lifetimes useful? - #4 by kornel
Mutable iterators are a common case where this is necessary. There's no way to explain to the borrow checker that
next()returns a different, non-overlapping mutable borrow each time if they all come from the same source. This can be reduced to implementation ofslice.split_at_mut(), which also requires such fudge.
And indeed, this works:
impl Buffer {
fn pop(&mut self) -> Option<Borrowed<'_>> {
loop {
let mutable = Mutable {
buf: &mut self.buf[..10],
};
if mutable.buf[0] == 0 {
let mutable: Mutable<'_> = unsafe { std::mem::transmute(mutable) };
return Some(mutable.borrow());
}
}
}
}
..but I certainly wouldn't feel good shipping that (even though miri seems happy with it)
@steffahn below (I can't reply anymore, Discourse hates me because I just signed up for it) mentioned polonius-the-crab, for the curious here's how it would look for the toy case. (This doesn't actually build on the playground, I guess it's not one of the top 100 crates)