A variable is moved depending on a condition (borrow checker)

Hey all,

I am trying to understand how the borrow checker works and came across this example:

struct Person {
    name: String
}

impl std::ops::Drop for Person {
    fn drop(&mut self) {
        println!("Dropping: {}", self.name);
    }
}

fn condition() -> bool {
    8 < 7
}

fn main() {
    let p;
    {
        let q = Person { name: String::from("Tom") };
        if condition() {
            p = q
        }
    }
    println!("End of scope");
}

If condition() returns true, then the value owned by the q is moved into p. Otherwise p remains uninitialized.
In the first case, p will go out of scope after the println!("End of scope") statement and thus the program output will be:

End of scope
Dropping: Tom

In the second case, q goes out of scope before the println!("End of scope") statement and thus the program output will be:

Dropping: Tom
End of scope

My question is as follows: condition() could be very complicated or even depend on values that are only known at runtime (user input etc.). How does the borrow checker know which variable will hold the value? Is this determined at compile time without evaluating the condition() function?

Thanks!

For situations where a variable might or might not be initialized, the compiler will insert a boolean variable to keep track of whether the destructor needs to run. These are called drop flags.

3 Likes

Huh, I thought this wouldn't compile! I might have some Options I can remove.

Note that p can't be used following the block in which it is assigned; the only effect of this is when the destructor runs.