diff options
| author | gingerBill <bill@gingerbill.org> | 2024-02-08 13:41:02 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-02-08 13:41:02 +0000 |
| commit | 59933b244ded0ab2476535b18875de95cd9f47bc (patch) | |
| tree | 532b205e9d433169fd07fd1d6d35539761e34ead /src/types.cpp | |
| parent | 42aca72d9f615b51b284b98e787dd6df8e7ba2d1 (diff) | |
Allow polymorphic checking with `intrinsics.type_is_subtype_of(Derived_Type, Poly_Type)`
Diffstat (limited to 'src/types.cpp')
| -rw-r--r-- | src/types.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/src/types.cpp b/src/types.cpp index b99d469e4..c4b03c967 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -4093,7 +4093,7 @@ gb_internal i64 type_offset_of_from_selection(Type *type, Selection sel) { return offset; } -gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0, bool src_is_ptr = false) { +gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isize level = 0, bool src_is_ptr = false, bool allow_polymorphic=false) { Type *prev_src = src; src = type_deref(src); if (!src_is_ptr) { @@ -4105,11 +4105,19 @@ gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isi return 0; } + bool dst_is_polymorphic = is_type_polymorphic(dst); + for_array(i, src->Struct.fields) { Entity *f = src->Struct.fields[i]; if (f->kind != Entity_Variable || (f->flags&EntityFlags_IsSubtype) == 0) { continue; } + if (allow_polymorphic && dst_is_polymorphic) { + Type *fb = base_type(type_deref(f->type)); + if (fb->kind == Type_Struct && fb->Struct.polymorphic_parent == dst) { + return true; + } + } if (are_types_identical(f->type, dst)) { return level+1; @@ -4119,7 +4127,7 @@ gb_internal isize check_is_assignable_to_using_subtype(Type *src, Type *dst, isi return level+1; } } - isize nested_level = check_is_assignable_to_using_subtype(f->type, dst, level+1, src_is_ptr); + isize nested_level = check_is_assignable_to_using_subtype(f->type, dst, level+1, src_is_ptr, allow_polymorphic); if (nested_level > 0) { return nested_level; } @@ -4135,6 +4143,13 @@ gb_internal bool is_type_subtype_of(Type *src, Type *dst) { return 0 < check_is_assignable_to_using_subtype(src, dst, 0, is_type_pointer(src)); } +gb_internal bool is_type_subtype_of_and_allow_polymorphic(Type *src, Type *dst) { + if (are_types_identical(src, dst)) { + return true; + } + + return 0 < check_is_assignable_to_using_subtype(src, dst, 0, is_type_pointer(src), true); +} gb_internal bool has_type_got_objc_class_attribute(Type *t) { |