Cannot borrow `element.1` as mutable more than once at a time

    for mut element in hash_map {
        let id = element.0;

        if element.1.len() != 2 {
            continue;
        }

        let first_element = element.1.get_mut(0).unwrap();
        let first_scale_pad = first_element.0;
        let mut first_transform = first_element.1.as_mut();

        let second_element = element.1.get_mut(1).unwrap();
        let second_scale_pad = second_element.0;
        let mut second_transform = second_element.1.as_mut();

        if first_scale_pad.circleable_value.unwrap()
            > second_scale_pad.circleable_value.unwrap()
        {
            first_transform.rotate_z(40.);
        }
    }

Error:

error[E0499]: cannot borrow `element.1` as mutable more than once at a time
  --> src/scalepad.rs:63:30
   |
59 |         let first_element = element.1.get_mut(0).unwrap();
   |                             -------------------- first mutable borrow occurs here
...
63 |         let second_element = element.1.get_mut(1).unwrap();
   |                              ^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
...
70 |             first_transform.rotate_z(40.);
   |             ----------------------------- first borrow later used here

Hello everyone, I'm very sorry for the repetitive post, since there are many like this, but I can't figure out how can I fix this.
I know that you cannot mutably borrow two times, however I cannot clone this type (element.1 is a Vec<(&ScalePad, Mut<Transform>)>, ScalePad is just a custom bevy component). So what do I do?

There are a few different ways to get mutable references to different indexes.

Here's one:

let (first_element, rest) = element.1.split_first_mut();
let second_element = &mut rest[0];

There are several variations on this. For example, there's also split_at_mut that takes an index and returns two subslices.

Another option is an iterator:

let mut element1_iter = element.1.iter_mut();
let first_element = element1_iter.next().unwrap();
let second_element = element1_iter.next().unwrap();

You can also match:

let (first, second) = match element.1.as_slice_mut() {
    [first, second] => (first, second),
    _ => continue,
}
3 Likes

Try something like

    for mut element in hash_map {
        let id = element.0;

        let [first_element, second_element] = &mut element.1[..] else {
            continue;
        };

        let first_scale_pad = first_element.0;
        let mut first_transform = first_element.1.as_mut();
        
        let second_scale_pad = second_element.0;
        let mut second_transform = second_element.1.as_mut();

        if first_scale_pad.circleable_value.unwrap()
            > second_scale_pad.circleable_value.unwrap()
        {
            first_transform.rotate_z(40.);
        }
    }
2 Likes

Thank you both, I spent way too much time on this!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.