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

时间:2017-08-23 19:00:38

标签: rust borrow-checker

section 3.2 of the Nomicon中,在“活跃”标题下,它说

  

然而,通常情况下Rust并不够聪明   证明多个借用是不相交的。

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

1 个答案:

答案 0 :(得分:3)

关键在上一句话中:

  

Rust明确地允许[重新借用多个可变引用]以使用不相交的结构字段来完成,因为可以静态地证明不相交

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

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
  

这会发生在元组结构中吗?

不是特别因为它是一个元组结构,但是,它可能出于同样的原因。如果从函数调用中获得借用,则会遇到与“传统”结构相同的问题。