Immutable slices of mutable references

⚓ rust    📅 2025-05-24    👤 surdeus    👁️ 4      

surdeus

Warning

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

I was trying to write a function that would remove a key from a slice of hashmaps if that key exists in all the hashmaps.

I started with something like this:

fn remove_common_k(maps: &[&mut HashMap<String, String>]) {
    let all_have_key = maps.iter().all(|m| m.contains_key("thekey"));

    if all_have_key {
        for map in maps {
            map.remove("thekey")
        }
    }
}

map is of type &&mut HashMap<String, String>, and the remove statement is an error because it is "behind an immutable reference". I wasn't able to dereference this to just &mut HashMap<String, String>.

My naive thought was that, although the slice itself is immutable, the values are mutable references, so it should be safe to modify the content of map because the actual reference to map is not changing.

But then, thinking further, I considered that since maps is an immutable reference, and you're allowed to have as many immutable references as you like, that if you could get a mutable reference from inside an immutably referenced slice, you'd be able to violate the rule about only having a single mutable reference like this:

fn remove_common_vals(maps: &[&mut HashMap<String, String>]) {
    let maps1 = maps;
    let maps2 = maps;
    // Rust won't like this:
    let map1 = maps1[0];
    let map2 = maps2[0];
    // because now I have two mutable references to the same data.
}

Therefore, Rust can't allow you to mutate something through an immutable reference (ie., something mutable inside something immutable, even if it's a reference to somewhere else).

My questions are:

  1. Am I thinking about this in the right way?
  2. Does it ever make sense to have a mutable reference inside of an immutable reference?
    b. If not, should there be a clippy about this not having utility?
  3. What should the signature of such a function look like? &mut[&mut HashMap<String, String>]?

3 posts - 3 participants

Read full topic

🏷️ rust_feed