diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 7f079e5bf..cbdd4e832 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -709,7 +709,8 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } Entity *other = gen_procs->procs[i]; Type *pt = base_type(proc_entity_full_type(other)); - if (are_types_identical(pt, final_proc_type)) { + // NOTE(bill): parameter names need to be included too as `typeid`s and link names include them + if (are_types_identical_unique_tuples(pt, final_proc_type)) { rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex if (poly_proc_data) { @@ -755,7 +756,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E } Entity *other = gen_procs->procs[i]; Type *pt = base_type(proc_entity_full_type(other)); - if (are_types_identical(pt, final_proc_type)) { + if (are_types_identical_unique_tuples(pt, final_proc_type)) { rw_mutex_shared_unlock(&gen_procs->mutex); // @local-mutex return reuse_gen_polymorphic_procedure(other, poly_proc_data); } @@ -770,7 +771,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E rw_mutex_lock(&gen_procs->mutex); // @local-mutex for_array(i, gen_procs->procs) { Entity *other = gen_procs->procs[i]; - if (gen_procs->hashes[i] == final_hash && are_types_identical(base_type(proc_entity_full_type(other)), final_proc_type)) { + if (gen_procs->hashes[i] == final_hash && are_types_identical_unique_tuples(base_type(proc_entity_full_type(other)), final_proc_type)) { rw_mutex_unlock(&gen_procs->mutex); // @local-mutex return reuse_gen_polymorphic_procedure(other, poly_proc_data); } diff --git a/src/types.cpp b/src/types.cpp index 02b73229e..3a8268271 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3230,64 +3230,10 @@ gb_internal bool lookup_subtype_polymorphic_selection(Type *dst, Type *src, Sele gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names); gb_internal bool are_types_identical(Type *x, Type *y) { - if (x == y) { - return true; - } - - if ((x == nullptr && y != nullptr) || - (x != nullptr && y == nullptr)) { - return false; - } - - if (x->kind == Type_Named) { - Entity *e = x->Named.type_name; - if (e->TypeName.is_type_alias) { - x = x->Named.base; - } - } - if (y->kind == Type_Named) { - Entity *e = y->Named.type_name; - if (e->TypeName.is_type_alias) { - y = y->Named.base; - } - } - if (x == nullptr || y == nullptr || x->kind != y->kind) { - return false; - } - - // MUTEX_GUARD(&g_type_mutex); return are_types_identical_internal(x, y, false); } + gb_internal bool are_types_identical_unique_tuples(Type *x, Type *y) { - if (x == y) { - return true; - } - - if (!x | !y) { - return false; - } - - if (x->kind == Type_Named) { - Entity *e = x->Named.type_name; - if (e->TypeName.is_type_alias) { - x = x->Named.base; - } - } - if (y->kind == Type_Named) { - Entity *e = y->Named.type_name; - if (e->TypeName.is_type_alias) { - y = y->Named.base; - } - } - if (x->kind != y->kind) { - return false; - } - - // if (x->canonical_hash && y->canonical_hash && x->canonical_hash != y->canonical_hash) { - // return false; - // } - - // MUTEX_GUARD(&g_type_mutex); return are_types_identical_internal(x, y, true); } @@ -3312,7 +3258,6 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple // return false; // } - #if 0 if (x->kind == Type_Named) { Entity *e = x->Named.type_name; if (e->TypeName.is_type_alias) { @@ -3325,14 +3270,13 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple y = y->Named.base; } } - if (x->kind != y->kind) { + if (x == nullptr || y == nullptr || x->kind != y->kind) { return false; } - #endif switch (x->kind) { case Type_Generic: - return are_types_identical(x->Generic.specialized, y->Generic.specialized); + return are_types_identical_internal(x->Generic.specialized, y->Generic.specialized, check_tuple_names); case Type_Basic: return x->Basic.kind == y->Basic.kind; @@ -3340,31 +3284,31 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple case Type_EnumeratedArray: return x->EnumeratedArray.count == y->EnumeratedArray.count && x->EnumeratedArray.is_sparse == y->EnumeratedArray.is_sparse && - are_types_identical(x->EnumeratedArray.index, y->EnumeratedArray.index) && - are_types_identical(x->EnumeratedArray.elem, y->EnumeratedArray.elem); + are_types_identical_internal(x->EnumeratedArray.index, y->EnumeratedArray.index, check_tuple_names) && + are_types_identical_internal(x->EnumeratedArray.elem, y->EnumeratedArray.elem, check_tuple_names); case Type_Array: - return (x->Array.count == y->Array.count) && are_types_identical(x->Array.elem, y->Array.elem); + return (x->Array.count == y->Array.count) && are_types_identical_internal(x->Array.elem, y->Array.elem, check_tuple_names); case Type_Matrix: return x->Matrix.row_count == y->Matrix.row_count && x->Matrix.column_count == y->Matrix.column_count && x->Matrix.is_row_major == y->Matrix.is_row_major && - are_types_identical(x->Matrix.elem, y->Matrix.elem); + are_types_identical_internal(x->Matrix.elem, y->Matrix.elem, check_tuple_names); case Type_DynamicArray: - return are_types_identical(x->DynamicArray.elem, y->DynamicArray.elem); + return are_types_identical_internal(x->DynamicArray.elem, y->DynamicArray.elem, check_tuple_names); case Type_FixedCapacityDynamicArray: return (x->FixedCapacityDynamicArray.capacity == y->FixedCapacityDynamicArray.capacity) && - are_types_identical(x->FixedCapacityDynamicArray.elem, y->FixedCapacityDynamicArray.elem); + are_types_identical_internal(x->FixedCapacityDynamicArray.elem, y->FixedCapacityDynamicArray.elem, check_tuple_names); case Type_Slice: - return are_types_identical(x->Slice.elem, y->Slice.elem); + return are_types_identical_internal(x->Slice.elem, y->Slice.elem, check_tuple_names); case Type_BitSet: - if (are_types_identical(x->BitSet.elem, y->BitSet.elem) && - are_types_identical(x->BitSet.underlying, y->BitSet.underlying)) { + if (are_types_identical_internal(x->BitSet.elem, y->BitSet.elem, check_tuple_names) && + are_types_identical_internal(x->BitSet.underlying, y->BitSet.underlying, check_tuple_names)) { if (is_type_enum(x->BitSet.elem)) { return true; } @@ -3380,7 +3324,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple if (x->Enum.fields.count != y->Enum.fields.count) { return false; } - if (!are_types_identical(x->Enum.base_type, y->Enum.base_type)) { + if (!are_types_identical_internal(x->Enum.base_type, y->Enum.base_type, check_tuple_names)) { return false; } if (x->Enum.min_value_index != y->Enum.min_value_index) { @@ -3418,7 +3362,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple // NOTE(bill): zeroth variant is nullptr for_array(i, x->Union.variants) { - if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) { + if (!are_types_identical_internal(x->Union.variants[i], y->Union.variants[i], check_tuple_names)) { return false; } } @@ -3433,7 +3377,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple x->Struct.is_all_or_none == y->Struct.is_all_or_none && x->Struct.soa_kind == y->Struct.soa_kind && x->Struct.soa_count == y->Struct.soa_count && - are_types_identical(x->Struct.soa_elem, y->Struct.soa_elem)) { + are_types_identical_internal(x->Struct.soa_elem, y->Struct.soa_elem, check_tuple_names)) { if (x->Struct.custom_align != y->Struct.custom_align) { if (type_align_of(x) != type_align_of(y)) { @@ -3447,7 +3391,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple if (xf->kind != yf->kind) { return false; } - if (!are_types_identical(xf->type, yf->type)) { + if (!are_types_identical_internal(xf->type, yf->type, check_tuple_names)) { return false; } if (xf->token.string != yf->token.string) { @@ -3469,13 +3413,13 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple break; case Type_Pointer: - return are_types_identical(x->Pointer.elem, y->Pointer.elem); + return are_types_identical_internal(x->Pointer.elem, y->Pointer.elem, check_tuple_names); case Type_MultiPointer: - return are_types_identical(x->MultiPointer.elem, y->MultiPointer.elem); + return are_types_identical_internal(x->MultiPointer.elem, y->MultiPointer.elem, check_tuple_names); case Type_SoaPointer: - return are_types_identical(x->SoaPointer.elem, y->SoaPointer.elem); + return are_types_identical_internal(x->SoaPointer.elem, y->SoaPointer.elem, check_tuple_names); case Type_Named: return x->Named.type_name == y->Named.type_name; @@ -3486,7 +3430,7 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple for_array(i, x->Tuple.variables) { Entity *xe = x->Tuple.variables[i]; Entity *ye = y->Tuple.variables[i]; - if (xe->kind != ye->kind || !are_types_identical(xe->type, ye->type)) { + if (xe->kind != ye->kind || !are_types_identical_internal(xe->type, ye->type, check_tuple_names)) { return false; } if (check_tuple_names) { @@ -3509,22 +3453,22 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple are_types_identical_internal(x->Proc.results, y->Proc.results, check_tuple_names); case Type_Map: - return are_types_identical(x->Map.key, y->Map.key) && - are_types_identical(x->Map.value, y->Map.value); + return are_types_identical_internal(x->Map.key, y->Map.key, check_tuple_names) && + are_types_identical_internal(x->Map.value, y->Map.value, check_tuple_names); case Type_SimdVector: if (x->SimdVector.count == y->SimdVector.count) { - return are_types_identical(x->SimdVector.elem, y->SimdVector.elem); + return are_types_identical_internal(x->SimdVector.elem, y->SimdVector.elem, check_tuple_names); } break; case Type_BitField: - if (are_types_identical(x->BitField.backing_type, y->BitField.backing_type) && + if (are_types_identical_internal(x->BitField.backing_type, y->BitField.backing_type, check_tuple_names) && x->BitField.fields.count == y->BitField.fields.count) { for_array(i, x->BitField.fields) { Entity *a = x->BitField.fields[i]; Entity *b = y->BitField.fields[i]; - if (!are_types_identical(a->type, b->type)) { + if (!are_types_identical_internal(a->type, b->type, check_tuple_names)) { return false; } if (a->token.string != b->token.string) {