rust-lang / rust-lang/rust

Mutable Borrow Enforced on Immutable Borrow

Open
#155,019 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-feature-request needs-triage
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.