How is `get_disjoint_mut` supposed to be used even?

⚓ Rust    📅 2025-08-16    👤 surdeus    👁️ 4      

surdeus

I'm trying to clone_from one element of a vector to another (without any temporary copy in between):

#[derive(Clone)]
struct MyBigStruct { ... }

fn myfunc(data: Vec<MyBigStruct>, from: usize, to: usize) {
    let indices = states
        .get_disjoint_mut([to as usize, from as usize])
        .expect("Failed to get disjoint indices");
    indices[0].clone_from(indices[1]);
    // ... rest of the function logic
}

However, this fails:

error[E0502]: cannot borrow `*indices[_]` as mutable because it is also borrowed as immutable
   --> src/main.rs:154:33
    |
154 | ...                   indices[0].clone_from(indices[1]);
    |                       ^^^^^^^^^^^----------^----------^
    |                       |          |          |
    |                       |          |          immutable borrow occurs here
    |                       |          immutable borrow later used by call
    |                       mutable borrow occurs here

For more information about this error, try `rustc --explain E0502`.

I also can't move out of the references from the indices array, as &mut isn't copy:

let from_state = indices[0];
let to_state = indices[1];
   --> src/main.rs:154:50
    |
154 | ...                   let from_state = indices[0];
    |                                        ^^^^^^^^^^
    |                                        |
    |                                        cannot move out of here
    |                                        move occurs because `indices[_]` has type `&mut StatemapInputDatum<CpuState>`, which does not implement the `Copy` trait
    |
help: consider borrowing here
    |
154 |                                 let from_state = &indices[0];
    |                                                  +

(Borrowing does not work, that just creates a &&mut, which is no help here. And this is performance critical code, I need to keep the number of indirections to a minimum.)

It seems to me that get_disjoint_mut is entirely useless if you can't actually work with multiple of the entries at once. I could use split_at_mut but then I need to figure out which index is larger and deal with computing offsets like that.

What is the best way to do this given that this that creates the ideal assembly (bounds check for from & to, check that they are different, then a simple clone)?

3 posts - 2 participants

Read full topic

🏷️ Rust_feed