Stable address map with UnsafePinned: Sound or not?
⚓ Rust 📅 2026-04-25 👤 surdeus 👁️ 1Every once in a while I want a collection that I can add to without invalidating pointers to its elements, useful for things like string interning.
I came up with an approach based on Box<UnsafePinned<T>>: the address is stable across reallocs because of the Box, and the immutable references can alias with the mutable reference to the map because of the UnsafePinned.
I can't decide if Pin is necessary here; the UnsafePinned docs seem a little unclear to me. It says that mem::swap asserts ownership of the swapped value, but I'm not sure if that's still true for Box<UnsafePinned<T>> because the address and allocation of the UnsafePinned are untouched when the box is swapped. (Leaving Pin off allows using the collection like normal when address stability is not necessary.)
I implemented a HashMap that uses this approach (playground link). It uses a guard to create a lifetime for the values, and it's a safety invariant that none of the methods on the guard can mutate/invalidate value references. There are a few other potential APIs, but I like how this one allows you to use it like a normal map until you request stability for a given lifetime.
Is this sound? If not, would it be sound with Pin? Miri doesn't complain with the example usage in the playground.
1 post - 1 participant
🏷️ Rust_feed