error[E0506]: cannot assign to `var` because it is borrowed

参照中の変数への書込を行った。

注意点

このエラー自体のルールは単純である。

しかし、エラーを読み解くには、参照まわりのその他の知識も必要になる事がある。

例えば、『ライフタイムの延長』の影響があると、初見では納得しにくいエラーになる。

メッセージ

メッセージの構成はだいたい以下のようになる。

要約部
  • 参照中の書込が検出された変数名
詳細部
  • 参照の発生個所 ← エラー個所より前方
  • 書込の発生個所 ← エラー個所
  • 参照の使用箇所 ← エラー個所より後方

パターン

パターン A

基本形

最も単純なパターン。

サンプル


fn main() {
    let mut var = 0;
    let var_ref = &var;
    var = 1;
    println!("{var}, {var_ref}");
}

error[E0506]: cannot assign to `var` because it is borrowed
 --> src\main.rs:4:5
  |
3 |     let var_ref = &var;
  |                   ---- `var` is borrowed here
4 |     var = 1;
  |     ^^^^^^^ `var` is assigned to here but it was already borrowed
5 |     println!("{var}, {var_ref}");
  |                       ------- borrow later used here

パターン B

Drop トレイトの影響

詳しくは『Drop トレイトのライフタイムへの影響 - ライフタイムの延長』を参照。
(注: Drop トレイトを直接的に扱っていなくても考慮が必要。)

サンプル


fn main() {
    let mut var = 1;
    let _refs = MyRef(&var);
    var = 2;
    dbg!(var);
}

struct MyRef<'a>(&'a i32);
impl Drop for MyRef<'_> {
    fn drop(&mut self) {
        println!("ID [{}] is drpoped.", self.0)
    }
}

error[E0506]: cannot assign to `var` because it is borrowed
 --> src\main.rs:4:5
  |
3 |     let _refs = MyRef(&var);
  |                       ---- `var` is borrowed here
4 |     var = 2;
  |     ^^^^^^^ `var` is assigned to here but it was already borrowed
5 |     dbg!(var);
6 | }
  | - borrow might be used here, when `_refs` is dropped and runs the `Drop` code for type `MyRef`