没有 drop 调用的 ManuallyDrop 不会导致内存泄漏吗?

Wouldnt ManuallyDrop without drop call cause memory leak?

我正在阅读 wasm-bindgen 指南,我遇到了它为 jsrust 之间的交互生成的 glue code。对值的引用从 js 传递给 rust。 Rust 必须将它包装在 ManuallyDrop 中,这样它就不会调用在 JsValue.

上实现的 Drop
pub fn foo(a: &JsValue) {
    // ...
}

#[export_name = "foo"]
pub extern "C" fn __wasm_bindgen_generated_foo(arg0: u32) {
    let arg0 = unsafe {
        ManuallyDrop::new(JsValue::__from_idx(arg0))
    };
    let arg0 = &*arg0;
    foo(arg0);
}

但我没有看到 ManuallyDrop::droparg0 上被调用。那么除非调用 ManuallyDrop::drop(arg0) 函数,否则包裹在 ManuallyDrop 中的 JsValue 会被删除吗?不会造成内存泄漏吗?

ManuallyDrop 并不能阻止内在价值被破坏。它只会阻止 drop 被调用。考虑 Vec:

pub struct Vec<T> {
    ptr: *mut T,
    cap: usize,
    len: usize,
}

字段 ptrcaplen仍然 被销毁,即使被 ManuallyDrop 包裹。但是,由于未调用 drop,因此不会释放任何管理的动态资源(在本例中为 ptr 引用的数据)。

因为 JsValue 只是持有一个 u32,所以 Rust 端不会发生泄漏。由于胶水代码确保 &JsValue 参数的正确清理,因此 Javascript 端没有内存泄漏。