Passing a mutable self reference to a mutable function of a struct member

⚓ Rust    📅 2025-11-17    👤 surdeus    👁️ 17      

surdeus

Warning

This post was published 62 days ago. The information described in this article may have changed.

I'm fairly new to Rust, and I'm not entirely sure how to get around the following problem, demonstrated in the example below.

struct B {}

struct A {
    b: B,
}

impl A {
    pub fn new() -> Self {
        return Self { b: B::new() };
    }

    pub fn mutable_func_1(&mut self) {
        println!("mutable_func_1");
        self.b.co_function(self);
    }

    pub fn mutable_func_2(&mut self) {
        println!("mutable_func_2");
    }
}

impl B {
    pub fn new() -> Self {
        return Self {};
    }

    pub fn co_function(&mut self, a: &mut A) {
        println!("co_function");
        a.mutable_func_2();
    }
}

fn main() {
    let mut a = A::new();
    a.mutable_func_1();
}

A owns a B internally, and would like to call a function on it where B may mutate A. Obviously A must be mutable in the first place, so mutable_func_1() uses &mut self. However, the compiler complains when calling into B:

error[E0499]: cannot borrow `self.b` as mutable more than once at a time
  --> src/main.rs:14:9
   |
14 |         self.b.co_function(self);
   |         ^^^^^^^-----------^----^
   |         |      |           |
   |         |      |           first mutable borrow occurs here
   |         |      first borrow later used by call
   |         second mutable borrow occurs here

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/main.rs:14:28
   |
14 |         self.b.co_function(self);
   |         ------ ----------- ^^^^ second mutable borrow occurs here
   |         |      |
   |         |      first borrow later used by call
   |         first mutable borrow occurs here

I'm struggling to understand how either b or self is borrowed more than once here. Is it possible to make this kind of call work?

6 posts - 4 participants

Read full topic

🏷️ Rust_feed