Pinning and hashing self address

Say I have a struct type Foo. I am trying to keep this type as tiny as possible because I am going to have a zillion instances. Most fields are accessed frequently but there are a few fields only need to be used under rare circumstances.

Instead of storing the rarely used fields directly in the struct, I would prefer to have a HashMap<*const Foo, RareFieldsStruct>. The idea being that when I needed the rare fields I would take the address of the Foo object I want the rare fields for, and look up the data in the hash table instead.

In the current version of my API users are only given access to &mut Foo by callback. As understand it even though they are getting a reference, they can still move the object by replacing or swapping. My question is: do I need to forbid this by giving Pin<&mut Foo> in the callbacks instead, in order to prevent unsoundness?

I think I don't need to use Pin. Because the object can only be replaced or swapped, there is still always going to be a Foo object at the memory referred to by the reference. As far as I can tell the worst that can happen by swapping is a sort of ABA problem, where if a user did a swap they would be looking up the rare fields of what used to be at that location instead of what is currently at that location. However, as long as any unsafe code I write does not rely on the assumption that this hasn't happened, I think I'm in the clear? Or is there some way that this could still be used to make things unsound? Another reason that I think it is sound is that I don't think I need any unsafe code to do this since I don't actually dereference any pointers, they are just used for hash table lookups.

I mean, it sounds like you could do this with safe code only, and in that case it would be guaranteed sound.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.