Mutable Borrow Enforced on Immutable Borrow
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Note: the provided example is contrived to demonstrate the error found in a more complex data structure.
pub struct Tracker<T> {
items: Vec<T>,
idx: usize,
}
impl<T> Tracker<T> {
pub fn new(items: Vec<T>) -> Self {
Self { items, idx: 0 }
}
pub fn next(&mut self) -> Option<(usize, &T)> {
let ret = self.items.get(self.idx).map(|item| (self.idx, item));
self.idx += 1;
ret
}
pub fn remaining(&self) -> usize {
self.items.len() - self.idx
}
}
fn main() {
let items = vec![1, 2, 3];
let mut tracker = Tracker::new(items);
while let Some((idx, item)) = tracker.next() {
tracker.remaining();
println!("{idx}. {item}");
}
}
λ cargo check
Checking ownership_bug v0.1.0 (/home/dgmastertemple/Dropbox/Development/rust/ownership_bug)
error[E0502]: cannot borrow `tracker` as immutable because it is also borrowed as mutable
--> src/main.rs:24:9
|
23 | while let Some((idx, item)) = tracker.next() {
| ------- mutable borrow occurs here
24 | tracker.remaining();
| ^^^^^^^ immutable borrow occurs here
25 | println!("{idx}. {item}");
| ---- mutable borrow later used here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `ownership_bug` (bin "ownership_bug") due to 1 previous error
.next() does need a mutable borrow, but what it returns (in this case) does not need a mutable borrow.
On L24, where I try to obtain an immutable borrow of tracker, the only existing borrow is for item, which is an immutable reference.
However, my borrow for item on L25 is identified as mutable, which makes my immutable borrow illegal.
I would think that it would be appropriate to identify an immutable variable received from a mutable borrow as only an immutable borrow, because all mutations are complete.
ownership_bug on master [?] is 📦 v0.1.0 via 🦀 v1.96.0-nightly
λ cargo --version
cargo 1.96.0-nightly (cbb9bb8bd 2026-03-13)
ownership_bug on master [?] is 📦 v0.1.0 via 🦀 v1.96.0-nightly
λ rustc --version
rustc 1.96.0-nightly (1d8897a4e 2026-03-13)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproducer in src/main.rs and run cargo check with the reported Rust and Cargo versions to confirm E0502. Compare the borrow-checker behavior around Tracker::next, Tracker::remaining, and the println! use; done requires establishing whether the reported borrowing is intended and documenting or resolving that determination.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100