rustimmutabilityborrow

cannot borrow `hsets` as mutable because it is also borrowed as immutable


I want move elements of HashSet[0] to HashSet[1], but always encounter borrowed error: I try using a tmp vec to save the elemetns, but problem still exists:

use std::collections::HashSet;

fn main() {

    let mut hsets = vec![];


    hsets.push(HashSet::new());
    hsets[0].insert("a1");
    hsets[0].insert("a2");

    hsets.push(HashSet::new());
    hsets[1].insert("b1");
    hsets[1].insert("b2");

    // tmp vec save hsets[0]: [a1, a2]
    let mut arr = vec![];

    for v in &hsets[0] {
        arr.push(v);
    }

    for v2 in arr {
        hsets[1].insert(v2);
    }
}

Result:

error[E0502]: cannot borrow `hsets` as mutable because it is also borrowed as immutable
  --> src/main.rs:18:9
   |
13 |     for v in &hsets[0] {
   |               ----- immutable borrow occurs here
...
17 |     for v2 in arr {
   |               --- immutable borrow later used here
18 |         hsets[1].insert(v2);
   |         ^^^^^ mutable borrow occurs here

error: aborting due to previous error

Solution

  • I'm assuming you don't want to move the HashSets out of the Vec or de-allocate them, in which case you can do this:

    use std::collections::HashSet;
    
    fn main() {
        let mut hsets = vec![];
    
        // first set
        hsets.push(HashSet::new());
        hsets[0].insert("a1");
        hsets[0].insert("a2");
    
        // second set
        hsets.push(HashSet::new());
        hsets[1].insert("b1");
        hsets[1].insert("b2");
    
        dbg!(&hsets);
        assert_eq!(hsets[0].len(), 2);
        assert_eq!(hsets[1].len(), 2);
    
        // move elements from first set to second set
        let (first, second) = hsets.split_at_mut(1);
        second[0].extend(first[0].drain());
    
        dbg!(&hsets);
        assert_eq!(hsets[0].len(), 0);
        assert_eq!(hsets[1].len(), 4);
    }
    

    playground

    If you'd like to get a deeper understanding of why your code as-is doesn't compile then read How to get mutable references to two array elements at the same time?.