不合理"cannot borrow `a` as immutable because it is also borrowed as mutable"?

Unreasonable "cannot borrow `a` as immutable because it is also borrowed as mutable"?

我已经看到 并且我的问题不是重复的,因为我的代码启用了非词法生命周期。

我想知道是否有以下代码的根本原因:

fn f1(a: &u32) {
  print!("{:?}", a);
}

fn main() {
  let mut a = 3;
  let b = &mut a;
  f1(&a);
  *b += 1;
  print!("{:?}", b);
}

必须导致以下错误:

error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/bin/client/main.rs:91:6
   |
90 |   let b = &mut a;
   |           ------ mutable borrow occurs here
91 |   f1(&a);
   |      ^^ immutable borrow occurs here
92 |   *b += 1;
   |   ------- mutable borrow later used here

现在,我知道在行 f1(&a) 上,我们将有一个可变引用 (b) 和一个不可变引用 (&a),并且根据 these rules 这不可能发生。但是只有 1 个可变引用和 1 个不可变引用只有在它们的用法交错时才会导致问题,对吧?也就是说,理论上,Rust 不应该能够观察到 b&a 的存在范围内没有被使用,从而接受这个程序吗?

这只是编译器的限制吗?还是我在这里忽略了其他一些内存危险?

That is, in theory, shouldn't Rust be able to observe that b is not used within &a's existence, and thus accept this program?

也许吧,尽管在某些极端情况下这可能会成为问题。我希望优化在这里成为一个问题,例如最终 Rust 将能够最终将 &mut 标记为 noalias 而不会立即出现 LLVM 错误编译的东西,在这种情况下,如果允许的话,你的代码 是 UB。

Is this just a limitation of the compiler?

在这种情况下不,它实际上是语言规范的限制。有些情况是编译器的限制,比如循环突变,但在这里你试图做一些事情语言的规则明确和明确地禁止

即使 polonius 也不会改变这一点。