fixed: many bugs related to distinct types
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 4 Jan 2024 02:58:56 +0000 (20:58 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 4 Jan 2024 02:58:56 +0000 (20:58 -0600)
compiler/include/astnodes.h
compiler/include/types.h
compiler/src/types.c
compiler/src/wasm_emit.c
tests/distinct_types [new file with mode: 0644]
tests/distinct_types.onyx [new file with mode: 0644]

index 134c9fc64d5974fdbdc1fca6807ecb0bc50a74f6..a29b83a55b8cc0548317ef6b4d74ae56be27e0ae 100644 (file)
@@ -2166,7 +2166,7 @@ static inline CallingConvention type_function_get_cc(Type* type) {
 }
 
 static inline ParamPassType type_get_param_pass(Type* type) {
-    if (type_is_structlike_strict(type) && !type_struct_is_just_one_basic_value(type)) {
+    if (type_should_be_passed_like_a_struct(type) && !type_struct_is_just_one_basic_value(type)) {
         if (type_structlike_is_simple(type)) return Param_Pass_By_Multiple_Values;
         else                                 return Param_Pass_By_Implicit_Pointer;
     }
index 3df4e5d12c11324b5731568a94c2c07a602e7432..5ae8c205732654502a2c05d1bcd7f01fc20ab61a 100644 (file)
@@ -281,6 +281,7 @@ b32 type_is_structlike(Type* type);
 b32 type_is_structlike_strict(Type* type);
 u32 type_structlike_mem_count(Type* type);
 u32 type_structlike_is_simple(Type* type);
+b32 type_should_be_passed_like_a_struct(Type *type);
 b32 type_is_sl_constructable(Type* type);
 b32 type_constructed_from_poly(Type* base, struct AstType* from);
 Type* type_struct_is_just_one_basic_value(Type *type);
index 9f0d41e194ab6856881a95f37591b4cec4198028..17dd8f5b42249071953147703658a8c11627473b 100644 (file)
@@ -1498,6 +1498,8 @@ b32 type_lookup_member(Type* type, char* member, StructMember* smem) {
 }
 
 b32 type_lookup_member_by_idx(Type* type, i32 idx, StructMember* smem) {
+    while (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
+
     if (type->kind == Type_Kind_Pointer) type = type->Pointer.elem;
 
     switch (type->kind) {
@@ -1565,11 +1567,14 @@ i32 type_linear_member_count(Type* type) {
         case Type_Kind_VarArgs:  return 2;
         case Type_Kind_Function: return 3;
         case Type_Kind_Compound: return bh_arr_length(type->Compound.linear_members);
+        case Type_Kind_Distinct: return type_linear_member_count(type->Distinct.base_type);
         default: return 1;
     }
 }
 
 b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) {
+    while (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
+
     switch (type->kind) {
         case Type_Kind_Slice:
         case Type_Kind_VarArgs: {
@@ -1607,11 +1612,6 @@ b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) {
         }
         case Type_Kind_Compound: *two = type->Compound.linear_members[idx]; return 1;
 
-        case Type_Kind_Distinct:
-            two->type = type->Distinct.base_type;
-            two->offset = 0;
-            return 1;
-
         case Type_Kind_Function:
             if (idx == 0) {
                 two->type = &basic_types[Basic_Kind_U32];
@@ -1637,6 +1637,8 @@ b32 type_linear_member_lookup(Type* type, i32 idx, TypeWithOffset* two) {
 }
 
 i32 type_get_idx_of_linear_member_with_offset(Type* type, u32 offset) {
+    while (type->kind == Type_Kind_Distinct) type = type->Distinct.base_type;
+
     switch (type->kind) {
         case Type_Kind_Slice:
         case Type_Kind_VarArgs: {
@@ -1775,6 +1777,9 @@ b32 type_is_structlike(Type* type) {
         if (type->Pointer.elem->kind == Type_Kind_DynArray) return 1;
         if (type->Pointer.elem->kind == Type_Kind_Union) return 1;
     }
+    if (type->kind == Type_Kind_Distinct) {
+        return type_is_structlike(type->Distinct.base_type);
+    }
     return 0;
 }
 
@@ -1789,6 +1794,18 @@ b32 type_is_structlike_strict(Type* type) {
     return 0;
 }
 
+b32 type_should_be_passed_like_a_struct(Type *type) {
+    if (type == NULL) return 0;
+    if (type->kind == Type_Kind_Struct)   return 1;
+    if (type->kind == Type_Kind_Slice)    return 1;
+    if (type->kind == Type_Kind_DynArray) return 1;
+    if (type->kind == Type_Kind_Function) return 1;
+    if (type->kind == Type_Kind_VarArgs)  return 1;
+    if (type->kind == Type_Kind_Union)    return 1;
+    if (type->kind == Type_Kind_Distinct) return type_should_be_passed_like_a_struct(type->Distinct.base_type);
+    return 0;
+}
+
 u32 type_structlike_mem_count(Type* type) {
     if (type == NULL) return 0;
     switch (type->kind) {
@@ -1797,7 +1814,7 @@ u32 type_structlike_mem_count(Type* type) {
         case Type_Kind_VarArgs:  return 2;
         case Type_Kind_Function: return 3;
         case Type_Kind_DynArray: return 4;
-        case Type_Kind_Distinct: return 1;
+        case Type_Kind_Distinct: return type_structlike_mem_count(type->Distinct.base_type);
         case Type_Kind_Union:    return 2;
         default: return 0;
     }
@@ -1809,6 +1826,7 @@ u32 type_structlike_is_simple(Type* type) {
         case Type_Kind_Slice:    return 1;
         case Type_Kind_VarArgs:  return 1;
         case Type_Kind_Function: return 1;
+        case Type_Kind_Distinct: return type_structlike_is_simple(type->Distinct.base_type);
         default: return 0;
     }
 }
index bac95f334f9186e1008cca9317ee85e688822538..c1a1fd0b0e510512e33dcfc4276a587485d88eaa 100644 (file)
@@ -27,7 +27,7 @@
 #define WASM_TYPE_VOID    0x00
 
 static b32 onyx_type_is_stored_in_memory(Type *type) {
-    if (type->kind == Type_Kind_Distinct) {
+    while (type->kind == Type_Kind_Distinct) {
         type = type->Distinct.base_type;
     }
 
@@ -4242,6 +4242,9 @@ EMIT_FUNC(zero_value_for_type, Type* type, OnyxToken* where, AstTyped *alloc_nod
         WIL(NULL, WI_I32_CONST, 0);
         WIL(NULL, WI_I32_CONST, 0);
 
+    } else if (type->kind == Type_Kind_Distinct) {
+        emit_zero_value_for_type(mod, &code, type->Distinct.base_type, where, alloc_node);
+
     } else {
         if (type == &basic_types[Basic_Kind_Void]) {
             return;
diff --git a/tests/distinct_types b/tests/distinct_types
new file mode 100644 (file)
index 0000000..24e61d2
--- /dev/null
@@ -0,0 +1,5 @@
+MyString[this works]
+Some(MyString["an optional works"])
+MyString[an optional works]
+MyString[an optional works]
+MyString[an optional works]
diff --git a/tests/distinct_types.onyx b/tests/distinct_types.onyx
new file mode 100644 (file)
index 0000000..f1a17c8
--- /dev/null
@@ -0,0 +1,21 @@
+package main
+
+use core {*}
+
+MyString :: #distinct str
+
+main :: () {
+    x := MyString.{ "this works" };
+
+    y: ? MyString = MyString.{ "an optional works" };
+
+    println(x);
+    println(y);
+    println(y->unwrap());
+    println(y ?? MyString.{"alternate"});
+
+    z := y ?? x;
+    printf("{}\n", z);
+}
+
+