当所有权可能在运行时移动时,Rust 编译器如何知道何时调用 drop?

How does the Rust compiler know when to invoke drop when ownership may be moved during runtime?

根据The Rust Programming Language

In Rust, you can specify that a particular bit of code be run whenever a value goes out of scope, and the compiler will insert this code automatically

程序员不应该显式地释放资源(从 Drop trait 调用 drop 函数),Rust 会在所有者离开范围时调用 drop,而这是在 compile 时间内完成的,但是如果它依赖于 runtime 信息,Rust 怎么可能知道何时调用 drop 呢?

extern crate rand;
use rand::Rng;

struct Foo {}

impl Drop for Foo {
    fn drop(&mut self) {
        println!("drop occurs");
    }
}

fn main() {
    let foo = Foo {};
    if rand::thread_rng().gen() {
        let _t = foo; // move foo to _t
    } //   1) drop occurs here if random bool is true
} //       2) drop occurs here if random bool is false

在这段代码中,当编译器插入代码释放资源时,drop的调用会放在哪里,放在1)2)?由于这在编译时无法获知,所以我认为调用应该放在两个地方,但只能调用一个以避免悬挂指针。

Rust 如何处理这种情况以保证内存安全?

Drop flags:

It turns out that Rust actually tracks whether a type should be dropped or not at runtime. As a variable becomes initialized and uninitialized, a drop flag for that variable is toggled. When a variable might need to be dropped, this flag is evaluated to determine if it should be dropped.