Borrow pointer errors recursively traversing tree [duplicate]

This seems to be a weakness of the borrow checker, and is perhaps a bug. The problem is that you are borrowing at in the match and then modifying it. Unfortunately, the compiler doesn’t see that the at inside the loop and outside the loop are conceptually different. We can make them explicitly different, however:

enum AVLTree {
    Tree(Box<AVLTree>),
    Empty,
}

impl AVLTree {
    fn insert_element(&mut self) {
        let mut at = self;
        loop {
            let tmp_at = at; // Main change
            match tmp_at {
                &mut AVLTree::Tree(ref mut left) => {
                    at = &mut **left;
                }
                &mut AVLTree::Empty => unreachable!()
            }
        }
    }
}

fn main() {}

Here, we transfer the mutable borrow from at to tmp_at, then transfer it to left, then transfer it back to at.

A prettier option may be to use a new scope:

fn insert_element(&mut self) {
    let mut at = self;
    loop {
        match {at} { // Main change
            &mut AVLTree::Tree(ref mut left) => {
                at = &mut **left;
            }
            &mut AVLTree::Empty => unreachable!(),
        }
    }
}

Leave a Comment