Browse Source

fix `specific_union_variant in map_keyed_by_union` not converting to union type

Laytan Laats 1 year ago
parent
commit
4d1d754cae
2 changed files with 26 additions and 4 deletions
  1. 6 4
      src/llvm_backend.cpp
  2. 20 0
      tests/internal/test_map.odin

+ 6 - 4
src/llvm_backend.cpp

@@ -976,14 +976,16 @@ gb_internal lbValue lb_const_hash(lbModule *m, lbValue key, Type *key_type) {
 gb_internal lbValue lb_gen_map_key_hash(lbProcedure *p, lbValue const &map_ptr, lbValue key, lbValue *key_ptr_) {
 	TEMPORARY_ALLOCATOR_GUARD();
 
-	lbValue key_ptr = lb_address_from_load_or_generate_local(p, key);
+	Type* key_type = base_type(type_deref(map_ptr.type))->Map.key;
+
+	lbValue real_key = lb_emit_conv(p, key, key_type);
+
+	lbValue key_ptr = lb_address_from_load_or_generate_local(p, real_key);
 	key_ptr = lb_emit_conv(p, key_ptr, t_rawptr);
 
 	if (key_ptr_) *key_ptr_ = key_ptr;
 
-	Type* key_type = base_type(type_deref(map_ptr.type))->Map.key;
-
-	lbValue hashed_key = lb_const_hash(p->module, key, key_type);
+	lbValue hashed_key = lb_const_hash(p->module, real_key, key_type);
 	if (hashed_key.value == nullptr) {
 		lbValue hasher = lb_hasher_proc_for_type(p->module, key_type);
 

+ 20 - 0
tests/internal/test_map.odin

@@ -317,3 +317,23 @@ set_delete_random_key_value :: proc(t: ^testing.T) {
 		seed_incr += 1
 	}
 }
+
+@test
+test_union_key_should_not_be_hashing_specifc_variant :: proc(t: ^testing.T) {
+	Vec2 :: [2]f32
+	BoneId :: distinct int
+	VertexId :: distinct int
+	Id :: union {
+		BoneId,
+		VertexId,
+	}
+
+	m: map[Id]Vec2
+	defer delete(m)
+
+	bone_1: BoneId = 69
+	m[bone_1] = {4, 20}
+
+	testing.expect_value(t, bone_1 in m, true)
+	testing.expect_value(t, Id(bone_1) in m, true)
+}