Browse Source

Improve parapoly support for `^T` to `[^]$V` and vice versa

gingerBill 2 years ago
parent
commit
eb7a9c55b0
2 changed files with 52 additions and 0 deletions
  1. 12 0
      src/check_expr.cpp
  2. 40 0
      src/types.cpp

+ 12 - 0
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:

+ 40 - 0
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;