Working with identity (comparing equality of references/pointers)

That makes sense, but I wonder if there is any remark on that in the reference. I think if there isn't, it might be a good idea to describe this difference regarding behavior of non-zero-sized vs zero-sized types. I agree, however, that it may be surmised. I just didn't think of it. But still, I think it's a good idea to clarify that in the reference.

The only part in the "Type Layout" section where the layout of zero-sized types seems to be explained is in a side note on ():

Tuple Layout

Tuples do not have any guarantees about their layout.

The exception to this is the unit tuple ( () ) which is guaranteed as a zero-sized type to have a size of 0 and an alignment of 1.

You have a good point here. If T was a slice, then I guess I need to compare base address and length. But in my above example of RefId<'a, T>, T will automatically be required to be Sized. Thus comparing the base address is sufficient to check for equality (disregarding the corner case of zero-sized types), right?

Now with all that knowledge, what is the right way to implement a type RefId<'a, T> that can be used as a HashSet key? Your idea to include a length would double the key-size in order to fix the odd case of zero-sized types. Is there any way to disallow T to be zero-sized? Or would I need to add a remark to the RefId type to never use it with zero-sized types (which then doesn't get enforced by the compiler)?


As it doesn't seem possible to add a trait like !ZeroSized, I guess the best (or only) zero-cost way is to document the behavior for such a RefId type and to warn users to not use it with zero-sized types (or expect random behavior in that case).