()
| 987 | |
| 988 | #[test] |
| 989 | fn hash_collisions() { |
| 990 | // Create a type with controlled hash collisions |
| 991 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
| 992 | struct CollisionValue { |
| 993 | id: u32, |
| 994 | collision_group: u32, |
| 995 | } |
| 996 | |
| 997 | impl Hash for CollisionValue { |
| 998 | fn hash<H: Hasher>(&self, state: &mut H) { |
| 999 | // Only hash the collision_group, causing collisions |
| 1000 | self.collision_group.hash(state); |
| 1001 | } |
| 1002 | } |
| 1003 | |
| 1004 | #[derive(Debug, PartialEq, Eq, Hash)] |
| 1005 | struct CollisionType { |
| 1006 | id: TaggedId, |
| 1007 | value: CollisionValue, |
| 1008 | } |
| 1009 | |
| 1010 | impl HasId for CollisionType { |
| 1011 | type Id = TaggedId; |
| 1012 | |
| 1013 | fn id(&self) -> Self::Id { |
| 1014 | self.id |
| 1015 | } |
| 1016 | } |
| 1017 | |
| 1018 | impl<'heap> Decompose<'heap> for CollisionType { |
| 1019 | type Partial = CollisionValue; |
| 1020 | |
| 1021 | fn from_parts(id: TaggedId, partial: Interned<'heap, CollisionValue>) -> Self { |
| 1022 | Self { |
| 1023 | id, |
| 1024 | value: *partial.as_ref(), |
| 1025 | } |
| 1026 | } |
| 1027 | } |
| 1028 | |
| 1029 | let heap = Heap::new(); |
| 1030 | let map = InternMap::<CollisionType>::new(&heap); |
| 1031 | |
| 1032 | // Create values with the same hash but different equality |
| 1033 | let value1 = map.intern_partial(CollisionValue { |
| 1034 | id: 1, |
| 1035 | collision_group: 42, |
| 1036 | }); |
| 1037 | |
| 1038 | let value2 = map.intern_partial(CollisionValue { |
| 1039 | id: 2, |
| 1040 | collision_group: 42, |
| 1041 | }); |
| 1042 | |
| 1043 | // They should have different IDs despite hash collision |
| 1044 | assert_ne!(value1.id(), value2.id()); |
| 1045 | |
| 1046 | // Interning the same value again should return the same ID |
nothing calls this directly
no test coverage detected