I'm committing some crimes with hashbrown's RawTable
. In hashbrown the HashMap::drain_filter()
method returns a DrainFilter
, which contains a DrainFilterInner
, which contains a mutable reference to the RawTable
(because while iterating over the contents of the map/table it may need to modify it).
My bastardized map (MyMap
) uses RawTable
, but it stores an extra data structure alongside of the RawTable
. Whenever the collection is updated both structures need to be updated. This means that the DrainFilterInner
needs to store a mutable reference to MyMap
, which would mean:
pub fn drain_filter<F>(&mut self, f: F) -> DrainFilter<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
{
DrainFilter {
f,
inner: DrainFilterInner {
iter: unsafe { self.table.iter() },
map: &mut self,
},
}
}
This is clearly a no-no. So I created an MyMapInner
, and stuffed the RawTable
and my alternative data structure in that, so instead it's more in line with hashbrown's HashMap
:
pub fn drain_filter<F>(&mut self, f: F) -> DrainFilter<'_, K, V, F>
where
F: FnMut(&K, &mut V) -> bool,
{
DrainFilter {
f,
inner: DrainFilterInner {
iter: unsafe { self.table.iter() },
inner_map: &mut self.inner,
},
}
}
This works, but I realize I'm not sure why. It's clear why if I have a &mut self
I can't store the &mut self
in another structure. However, it's not clear to me why I can store a mutable reference to an inner struct of self
in a foreign struct.
My mental model was "I can't alias &mut self
, including anything inside it", but that's clearly insufficient.
What am I missing?