aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/typecheck.c6
-rw-r--r--src/types.c9
-rw-r--r--src/types.h1
3 files changed, 11 insertions, 5 deletions
diff --git a/src/typecheck.c b/src/typecheck.c
index 1ac3943c..a073cb2e 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -1531,11 +1531,7 @@ PUREFUNC bool is_discardable(env_t *env, ast_t *ast) {
case Metadata: return true;
default: break;
}
- type_t *t = get_type(env, ast);
- if (t->tag == StructType) {
- return (Match(t, StructType)->fields == NULL);
- }
- return (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType);
+ return is_discardable_type(get_type(env, ast));
}
type_t *get_arg_ast_type(env_t *env, arg_ast_t *arg) {
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;
diff --git a/src/types.h b/src/types.h
index 66e6ba12..df5729ca 100644
--- a/src/types.h
+++ b/src/types.h
@@ -142,6 +142,7 @@ PUREFUNC bool type_eq(type_t *a, type_t *b);
PUREFUNC bool type_is_a(type_t *t, type_t *req);
type_t *type_or_type(type_t *a, type_t *b);
type_t *value_type(type_t *a);
+PUREFUNC bool is_discardable_type(type_t *t);
typedef enum {
NUM_PRECISION_EQUAL,
NUM_PRECISION_LESS,