error[E0503]: cannot use `val` because it was mutably borrowed

可変参照中の値をその参照外から使用した。

注意点

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

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

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

メッセージ

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

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

パターン

パターン A

基本形

最も単純なパターン。

サンプル


fn main() {
    let mut val = 42;
    let mut_val = &mut val;
    work(val);
    work(mut_val);
}

fn work<T>(_x: T) {
    // nop.
}

error[E0503]: cannot use `val` because it was mutably borrowed
 --> src/main.rs:4:10
  |
3 |     let mut_val = &mut val;
  |                   -------- `val` is borrowed here
4 |     work(val);
  |          ^^^ use of borrowed `val`
5 |     work(mut_val);
  |          ------- borrow later used here

パターン B

Drop トレイトの影響

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

サンプル


fn main() {
    let mut var = 1;
    let _mut_var = MyMutRef(&mut var);
    work(var);
}

fn work<T>(_x: T) {
    // nop.
}

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

error[E0503]: cannot use `var` because it was mutably borrowed
 --> src\main.rs:4:10
  |
3 |     let _mut_var = MyMutRef(&mut var);
  |                             -------- `var` is borrowed here
4 |     work(var);
  |          ^^^ use of borrowed `var`
5 | }
  | - borrow might be used here, when `_mut_var` is dropped and runs the `Drop` code for type `MyMutRef`

パターン C

NLL の制限

2025 年現在の借用チェッカー NLL の偽陽性が原因になっている。

詳しくは『借用チェッカーの制限 - 偽陽性の例 1』を参照。