Description
Currently there is no compile-time or run-time protection of using a Key
from one SlotMap
on another. There is no unsafe behavior if this occurs, but it might be worth catching this error somehow anyway.
Some approaches were suggested.
-
Changing
Key
toKey<T>
, of the type of the slot map. This offers a little protection, but not much - you can still use keys between slot maps storing the same type of value. If you take into account that values are also actually used after retrieval, with typechecking, any undetected errors of using a key on the wrong slot map probably already stored values of the same type. -
Storing a unique id per slot map inside it and in the key as well and checking for equality when used. Quite expensive, so possibly only when debug mode is enabled. Arises questions of how such an unique id should be generated, and how the error should be reported. E.g. should
sm1.get(k2)
returnNone
or panic? (Probably panic). -
Starting the version field of each slot map on a random location to reduce the chance of a valid result when crossing keys. Not a fan of this, as it might actually make the problem harder and more spurious to detect, while still leaving the possibility of the error.
-
Adding a marker type
M
to bothSlotMap<T, M=()>
andKey<M=()>
that can be used to distinguish a slot map from any other if the user desires with their own new type. Stops all errors and is elegant, but has two issues. Users have to make their own newtypes to get this protection and it blows up code size (until this is fixed [WIP] Deduplicate instances rust-lang/rust#48139). -
Add a key type for the slot map, such that
SlotMap<T, K=Key> where K: Copy + From<Key> + Into<Key>
. This allows people to make key newtypes that can't be mixed/matched. Very similar to number 4.