From eb7a9c55b03efe0245eb4ccd1abd552edc99224d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 20 Sep 2022 22:47:53 +0100 Subject: [PATCH] Improve parapoly support for `^T` to `[^]$V` and vice versa --- src/check_expr.cpp | 12 ++++++++++++ src/types.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 891a9ebcb..196982084 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1143,6 +1143,12 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, return true; } return is_polymorphic_type_assignable(c, poly->Pointer.elem, source->Pointer.elem, true, modify_type); + } else if (source->kind == Type_MultiPointer) { + isize level = check_is_assignable_to_using_subtype(source->MultiPointer.elem, poly->Pointer.elem); + if (level > 0) { + return true; + } + return is_polymorphic_type_assignable(c, poly->Pointer.elem, source->MultiPointer.elem, true, modify_type); } return false; @@ -1153,6 +1159,12 @@ bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, Type *source, return true; } return is_polymorphic_type_assignable(c, poly->MultiPointer.elem, source->MultiPointer.elem, true, modify_type); + } else if (source->kind == Type_Pointer) { + isize level = check_is_assignable_to_using_subtype(source->Pointer.elem, poly->MultiPointer.elem); + if (level > 0) { + return true; + } + return is_polymorphic_type_assignable(c, poly->MultiPointer.elem, source->Pointer.elem, true, modify_type); } return false; case Type_Array: diff --git a/src/types.cpp b/src/types.cpp index e917d30fa..5ebc8689f 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2107,6 +2107,9 @@ bool is_type_polymorphic(Type *t, bool or_specialized=false) { case Type_Pointer: return is_type_polymorphic(t->Pointer.elem, or_specialized); + case Type_MultiPointer: + return is_type_polymorphic(t->MultiPointer.elem, or_specialized); + case Type_SoaPointer: return is_type_polymorphic(t->SoaPointer.elem, or_specialized); @@ -2130,6 +2133,15 @@ bool is_type_polymorphic(Type *t, bool or_specialized=false) { case Type_Slice: return is_type_polymorphic(t->Slice.elem, or_specialized); + case Type_Matrix: + if (t->Matrix.generic_row_count != nullptr) { + return true; + } + if (t->Matrix.generic_column_count != nullptr) { + return true; + } + return is_type_polymorphic(t->Matrix.elem, or_specialized); + case Type_Tuple: for_array(i, t->Tuple.variables) { if (is_type_polymorphic(t->Tuple.variables[i]->type, or_specialized)) { @@ -2196,6 +2208,34 @@ bool is_type_polymorphic(Type *t, bool or_specialized=false) { } break; + case Type_BitSet: + if (is_type_polymorphic(t->BitSet.elem, or_specialized)) { + return true; + } + if (t->BitSet.underlying != nullptr && + is_type_polymorphic(t->BitSet.underlying, or_specialized)) { + return true; + } + break; + + case Type_RelativeSlice: + if (is_type_polymorphic(t->RelativeSlice.slice_type, or_specialized)) { + return true; + } + if (t->RelativeSlice.base_integer != nullptr && + is_type_polymorphic(t->RelativeSlice.base_integer, or_specialized)) { + return true; + } + break; + case Type_RelativePointer: + if (is_type_polymorphic(t->RelativePointer.pointer_type, or_specialized)) { + return true; + } + if (t->RelativePointer.base_integer != nullptr && + is_type_polymorphic(t->RelativePointer.base_integer, or_specialized)) { + return true; + } + break; } return false;