Skip to content

nested mutable reference error #142039

Open
Open
@BennoLossin

Description

@BennoLossin

I tried this code (minified example, both lifetimes are required in the actual code):

struct Context<'a, 'b> {
    root: Item<'a>,
    path: Vec<&'b str>,
}

pub struct Item<'a> {
    pub items: HashMap<&'a str, Item<'a>>,
}

impl<'a, 'b> Context<'a, 'b> {
    fn find(&mut self) -> &mut Item<'a> {
        let mut res = &mut self.root;
        for seg in &self.path {
            res = res.items.get_mut(seg).unwrap();
        }
        res
    }
}

I expected to see this happen: successful compilation

Instead, this happened: compile error:

error: lifetime may not live long enough
  --> src/main.rs:14:23
   |
12 | impl<'a, 'b> Context<'a, 'b> {
   |      --  -- lifetime `'b` defined here
   |      |
   |      lifetime `'a` defined here
13 |     fn find(&mut self) -> &mut Item<'a> {
14 |         let mut res = &mut self.root;
   |                       ^^^^^^^^^^^^^^ assignment requires that `'b` must outlive `'a`
   |
   = help: consider adding the following bound: `'b: 'a`
   = note: requirement occurs because of a mutable reference to `Item<'_>`
   = note: mutable references are invariant over their type parameter
   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

The error is very unclear on what the actually problem is. It also doesn't seem an actual problem, since root doesn't mention 'b at all and intuitively it should work.

The following version works, which lets me guess it's some lifetime coercion issue:

fn explicit_get_mut<'a, 'c>(
    items: &'c mut HashMap<&str, Item<'a>>,
    seg: &str,
) -> &'c mut Item<'a> {
    items.get_mut(seg).unwrap()
}

fn find2(&mut self) -> &mut Item<'a> {
    let mut res: &mut Item<'a> = &mut self.root;
    for seg in &self.path {
        res = explicit_get_mut(&mut res.items, seg);
    }
    res
}

Meta

rustc --version --verbose:

rustc 1.89.0-nightly (99e7c15e8 2025-06-01)
binary: rustc
commit-hash: 99e7c15e81385b38a8186b51edc4577d5d7b5bdd
commit-date: 2025-06-01
host: x86_64-unknown-linux-gnu
release: 1.89.0-nightly
LLVM version: 20.1.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions