error[E0499]: cannot borrow `*self` as mutable more than once at a time

E0499 - 可変参照の重複 - NLL の偽陽性』は GAT でよく問題になる。

このエラーは 、GAT に残る制限の一つ。

サンプル


use std::slice::Iter;

fn main() {
    let vec = vec![1, 2, 3];
    let mut iter = MyIter(vec.iter());
    let third = *iter.nth(3).unwrap();
    assert_eq!(third, 3);
}

trait LendingIterator {
    type Item<'a> where Self: 'a;

    fn next(&mut self) -> Option<Self::Item<'_>>;

    fn nth(&mut self, n: usize) -> Option<Self::Item<'_>> {
        for i in 0..n {
            let item = self.next();
            if i == n {
                return item;
            }
        }

        None
    }
}

struct MyIter<'a, T>(Iter<'a, T>);

impl<'s, T> LendingIterator for MyIter<'s, T> {
    type Item<'a> = &'a T where Self: 'a;

    fn next(&mut self) -> Option<Self::Item<'_>> {
        (&mut self.0 as &mut dyn Iterator<Item = &T>).next()
    }
}

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src\main.rs:17:24
   |
15 |     fn nth(&mut self, n: usize) -> Option<Self::Item<'_>> {
   |            - let's call the lifetime of this reference `'1`
16 |         for i in 0..n {
17 |             let item = self.next();
   |                        ^^^^ `*self` was mutably borrowed here in the previous iteration of the loop
18 |             if i == n {
19 |                 return item;
   |                        ---- returning this value requires that `*self` is borrowed for `'1`

解決策

アンセーフなコードを利用して参照の監視を止めればよい。

例えば、前述のサンプルの場合、self.next() の箇所を、
unsafe { &mut *(self as *mut Self) }.next() とするといい。