Variable does not live long enough with closure

I'm stuck with the above error message in this code: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=280a52f4dc63204e7bb23bcfe8521e76

I'm using map on option for convenience. Somehow, the error has to do with the fact that secondary_node is captured in the closure. Without a closure (commented out code below), the same code works ok.
Is there a pattern that I have to use to make this work?

Thank you,

map isn't really meant to execute code if an option is Some; it's intended to transform options into other options. The if is the right way to go, though it's easier to write it with if let:

if let Some(ref l) = primary_node.left {
    let n = Box::new(Node::new(l.value));
    secondary_node.right = Some(n);
    queue.push_front((l, secondary_node.right.as_mut().unwrap()));
}
1 Like

When there's no closure, the compiler can reason about borrows to distinct parts of the node, but with a closure it just borrows the whole secondary_node.

You can manually get those distinct borrows and move them into the closure:

    while queue.is_empty() == false {
        let (primary_node, secondary_node) = queue.pop_back().unwrap();
        let left = &mut secondary_node.left;
        let right = &mut secondary_node.right;

        // SS: duplicate nodes
        {
            let queue = &mut queue; // manual reference to avoid moving the whole queue
            primary_node.left.as_ref().map(move |l| {
                let n = Box::new(Node::new(l.value));
                *right = Some(n);
                queue.push_front((l, right.as_mut().unwrap()));
            });
        }

        {
            let queue = &mut queue;
            primary_node.right.as_ref().map(move |r| {
                let n = Box::new(Node::new(r.value));
                *left = Some(n);
                queue.push_front((r, left.as_mut().unwrap()));
            });
        }
    }
1 Like

Thank you both very much, makes sense.