Rust 编译器什么时候不能证明借用是不相交的?

When can the Rust compiler not prove that borrows are disjoint?

section 3.2 of the Nomicon 中,标题 "liveness" 下显示

However it's often the case that Rust isn't sufficiently smart to prove that multiple borrows are disjoint.

Rust 编译器无法证明它们不相交的示例是什么?这会发生在元组结构中吗?

关键在前一句:

Rust explicitly enables [reborrowing into multiple mutable references] to be done with disjoint struct fields, because disjointness can be statically proven

在这种情况之外,编译器无法判断两个借用是不相交的。实际上,这意味着编译器无法判断函数调用产生的借用是不相交的。

struct Thing {
    a: i32,
    b: i32,
}
fn example_works(thing: &mut Thing) {
    let a = &mut thing.a;
    let b = &mut thing.b;
}
fn get_a(thing: &mut Thing) -> &mut i32 {
    &mut thing.a
}

fn get_b(thing: &mut Thing) -> &mut i32 {
    &mut thing.b
}

fn example_doesnt_work(thing: &mut Thing) {
    let a = get_a(thing);
    let b = get_b(thing);
    println!("{}, {}", a, b);
}
error[E0499]: cannot borrow `*thing` as mutable more than once at a time
  --> src/lib.rs:26:19
   |
25 |     let a = get_a(thing);
   |                   ----- first mutable borrow occurs here
26 |     let b = get_b(thing); // cannot borrow `*thing` as mutable more than once at a time
   |                   ^^^^^ second mutable borrow occurs here
27 |     println!("{}, {}", a, b);
   |                        - first borrow later used here

Will this ever occur in a tuple struct?

不具体因为它是一个元组结构,但是是的,它可能出于同样的原因发生。如果您从函数调用中获得借用,您将遇到与 "traditional" 结构相同的问题。