Why does re-borrowing only work on de-referenced pointers?

不打扰是莪最后的温柔 提交于 2021-02-10 14:23:28

问题


This question and code are adapted from Why does creating a mutable reference to a dereferenced mutable reference work?. The answers there explained re-borrowing but not the reasons for the conventions around it.

The two calls to test below seem equivalent, why does only the first one work?

fn main() {
    let mut string = String::new();
    let ref_string = &mut string;

    // Compiles
    test(&mut *ref_string);

    // Doesn't compile
    test(&mut string);
}

fn test(s: &mut String) {
    s.push('t');
}

回答1:


You are only allowed to have a single mutable reference to a value at a time. When you mutably reborrow as an argument, it's trivial for the compiler to see that you aren't going to be using ref_string at the same time and thus the code is safe.

My mental image is that there's a "chain of custody" for the mutability. ref_string is the holder and can temporarily give that up to the temporary created by &mut *ref_string. When that goes out of scope, the mutability is returned to it. It's as if the code were:

{
    let x = &mut *ref_string;
    test(x);
}

However, when you try to "go around" and get the mutable reference, you are ignoring the chain of custody. The compiler stops you because it cannot trivially see that it is safe.


Of note is that non-lexical lifetimes improves the original situation. When the MIR-based borrow checker is enabled, the compiler can see that ref_string is no longer in use by the time the second call to test happens, thus it's safe for the exclusive access to be transferred there.



来源:https://stackoverflow.com/questions/51015503/why-does-re-borrowing-only-work-on-de-referenced-pointers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!