Cannot borrow immutable borrowed content `*next` as mutable

Hello,

I have implemented this code:

fn update_next_node(next_node_id: &str, node: &mut Node) {
    let mut transition = node.get_next_mut(next_node_id);
    if let Some(trans) = transition {
        let mut next = trans.get_next_node();
        let distance = trans.get_weight();

        if next.get_value() > node.get_value() + distance {
            next.set_value( node.get_value() + distance);
        }
    }
}

The curent code is here.

Please advise how can I solve this 2 errors

error[E0596]: cannot borrow immutable borrowed content `*next` as mutable
  --> src\lib.rs:35:13
   |
35 |             next.set_value( node.get_value() + distance);
   |             ^^^^ cannot borrow as mutable

warning: variable does not need to be mutable
  --> src\lib.rs:29:9
   |
29 |     let mut transition = node.get_next_mut(next_node_id);
   |         ----^^^^^^^^^^
   |         |
   |         help: remove this `mut`
   |
   = note: #[warn(unused_mut)] on by default

error[E0596]: cannot borrow field `self.next` of immutable binding as mutable
  --> src\graph.rs:47:9
   |
46 |     pub fn get_next_mut(&self, id: &str) -> Option<&mut Transition<'a>> {
   |                         ----- use `&mut self` here to make mutable
47 |         self.next.get_mut(id)
   |         ^^^^^^^^^ cannot mutably borrow field of immutable binding

error: aborting due to 2 previous errors

Thank you

Corentin

Let's start with the last error, for the definition of the method get_next_mut. The function tries to return a mutable reference to a value inside of self.next, but the method is receiving an immutable reference &self to itself. As the compiler suggests, you'd need a &mut self mutable reference to be able to return a &mut reference.

Similarly, the variable next is initialized by trans.get_next_node() which currently returns an immutable reference; this method too needs to take a mutable reference to self and return a mutable reference if we're going to mutate the referenced value by calling next.set_value(...)

Hope this helps!

Thank you for your help. I have added &mut self for both method get_next_mutand get_next_node.

Github code was updated.

But I have 3 more errors:

   Compiling shortest-way v0.1.0 (file:///C:/Users/corentin/git/shortest-way-rs)
error[E0596]: cannot borrow immutable borrowed content `*next` as mutable] 0/1: shortest-way
  --> src\lib.rs:35:13
   |
35 |             next.set_value( node.get_value() + distance);
   |             ^^^^ cannot borrow as mutable

error[E0502]: cannot borrow `*node` as immutable because it is also borrowed as mutable
  --> src\lib.rs:34:31
   |
29 |     let mut transition = node.get_next_mut(next_node_id);
   |                          ---- mutable borrow occurs here
...
34 |         if next.get_value() > node.get_value() + distance {
   |                               ^^^^ immutable borrow occurs here
...
38 | }
   | - mutable borrow ends here

error[E0502]: cannot borrow `*node` as immutable because it is also borrowed as mutable
  --> src\lib.rs:35:29
   |
29 |     let mut transition = node.get_next_mut(next_node_id);
   |                          ---- mutable borrow occurs here
...
35 |             next.set_value( node.get_value() + distance);
   |                             ^^^^ immutable borrow occurs here
...
38 | }
   | - mutable borrow ends here

warning: variable does not need to be mutable
  --> src\lib.rs:29:9
   |
29 |     let mut transition = node.get_next_mut(next_node_id);
   |         ----^^^^^^^^^^
   |         |
   |         help: remove this `mut`
   |
   = note: #[warn(unused_mut)] on by default

error: aborting due to 3 previous errors

Looking at your updated GitHub link, the signature of get_next_node is

pub fn get_next_node(&mut self) -> &'a Node<'a> { ... }

The function is still returning an immutable reference, which you then try to use to modify the referenced value.

This error, and the error about borrowing *node, are covered in this chapter of the Rust book.

Word of advice: create a playground example that people can use, it’s much better than github links.

To that end, I copy/pasted the bulk of your code and then made adjustments to make the few unit tests to pass (and code to compile). play

I’m pretty sure there are aspects here that aren’t desirable (eg &'a mut Node<'a> sharing the same lifetime parameter) but I punted on thinking too much about it - there’s almost certainly a better design/API.

My suggestion would be to work through lifetimes/borrows carefully, perhaps re-read the book. Given you’re trying to get a mutable reference without holding a mutable borrow in some cases suggests you may want to brush up on this before going down the lifetime/reference journey :slight_smile:

Thank you for your help. I am progressing.