E4004
E4004 — Cannot borrow (already mutably borrowed)
What the compiler reports
Error[E4004] at {{.*}}method_returning_mut_keeps_its_receiver_borrowed_mutably.vx:[[@LINE+1]]:11: Cannot borrow 'c' because it is already borrowed as mutable.
The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.
A program that triggers it
//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//
// `c.get_mut()` returns a `&mut` into `c`, so `c` stays mutably borrowed while `r` is used, and
// no other borrow of `c` is allowed then.
struct C {
v : i32,
}
impl C {
fn get_mut(self : &mut C) -> &mut i32 {
return &mut self.v;
}
}
fn main() -> i32 {
let mut c = C {
v : 1
};
let r = c.get_mut();
let s = &c;
*r = 5;
return s.v;
}
From tests/frontend/fail/method_returning_mut_keeps_its_receiver_borrowed_mutably.vx, which asserts this diagnostic on every commit.
Related
Ownership and borrowingThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E4003Cannot borrow as mutable (already immutably borrowed)
E4005A value that points into this function's stack frame would outlive the function: a reference to a local, or a closure that uses one, returned (on its own or inside a struct), stored through a reference, or passed to a call that could store it there. What it points at is gone once the function returns. The same holds inside a function for a block: a variable declared outside a block cannot be given a value that points at a variable declared inside it. Nor can a variable keep a reference into a value with no name, such as
make_vec() in let r = &make_vec();, when that value is dropped at the end of its statement. A closure cannot return a reference to its own parameter, or to the copy it keeps of a variable it uses (|| &x): each call has its own frame.