From a1b92de7df8784b84f47818952b6a45f5f8cdb67 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Wed, 3 Jan 2024 20:58:56 -0600 Subject: [PATCH] fixed: many bugs related to distinct types --- compiler/include/astnodes.h | 2 +- compiler/include/types.h | 1 + compiler/src/types.c | 30 ++++++++++++++++++++++++------ compiler/src/wasm_emit.c | 5 ++++- tests/distinct_types | 5 +++++ tests/distinct_types.onyx | 21 +++++++++++++++++++++ 6 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 tests/distinct_types create mode 100644 tests/distinct_types.onyx diff --git a/compiler/include/astnodes.h b/compiler/include/astnodes.h index 134c9fc6..a29b83a5 100644 --- a/compiler/include/astnodes.h +++ b/compiler/include/astnodes.h @@ -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; } diff --git a/compiler/include/types.h b/compiler/include/types.h index 3df4e5d1..5ae8c205 100644 --- a/compiler/include/types.h +++ b/compiler/include/types.h @@ -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); diff --git a/compiler/src/types.c b/compiler/src/types.c index 9f0d41e1..17dd8f5b 100644 --- a/compiler/src/types.c +++ b/compiler/src/types.c @@ -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; } } diff --git a/compiler/src/wasm_emit.c b/compiler/src/wasm_emit.c index bac95f33..c1a1fd0b 100644 --- a/compiler/src/wasm_emit.c +++ b/compiler/src/wasm_emit.c @@ -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 index 00000000..24e61d2c --- /dev/null +++ b/tests/distinct_types @@ -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 index 00000000..f1a17c83 --- /dev/null +++ b/tests/distinct_types.onyx @@ -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); +} + + -- 2.25.1