aboutsummaryrefslogtreecommitdiff
path: root/src/types.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/types.c')
-rw-r--r--src/types.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/types.c b/src/types.c
index 46df5c64..1ccb7952 100644
--- a/src/types.c
+++ b/src/types.c
@@ -144,6 +144,13 @@ PUREFUNC type_t *value_type(type_t *t) {
return t;
}
+PUREFUNC bool is_discardable_type(type_t *t) {
+ if (t->tag == StructType) {
+ return (Match(t, StructType)->fields == NULL);
+ }
+ return (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType);
+}
+
type_t *type_or_type(type_t *a, type_t *b) {
if (!a) return b;
if (!b) return a;
@@ -153,6 +160,8 @@ type_t *type_or_type(type_t *a, type_t *b) {
return a->tag == OptionalType ? a : Type(OptionalType, a);
if (a->tag == ReturnType && b->tag == ReturnType)
return Type(ReturnType, .ret = type_or_type(Match(a, ReturnType)->ret, Match(b, ReturnType)->ret));
+ if ((a->tag == VoidType && is_discardable_type(b)) || (is_discardable_type(a) && b->tag == VoidType))
+ return Type(VoidType);
if (is_incomplete_type(a) && type_eq(b, most_complete_type(a, b))) return b;
if (is_incomplete_type(b) && type_eq(a, most_complete_type(a, b))) return a;