commit 4f3f7801a2e5fdce901e6a8c1ff445d288772599
parent bddf034db646a1d7f9e934527b4d35354fbe69cd
Author: Bor Grošelj Simić <bor.groseljsimic@telemach.net>
Date: Sun, 25 Apr 2021 04:16:15 +0200
forbid tagged unions with a single member
Signed-off-by: Bor Grošelj Simić <bor.groseljsimic@telemach.net>
Diffstat:
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/src/type_store.c b/src/type_store.c
@@ -358,7 +358,7 @@ tagged_cmp(const void *ptr_a, const void *ptr_b)
: (*a)->type->id > (*b)->type->id ? 1 : 0;
}
-static void
+static size_t
tagged_init(struct type *type, struct type_tagged_union **tu, size_t nmemb)
{
// Prune duplicates
@@ -412,6 +412,8 @@ tagged_init(struct type *type, struct type_tagged_union **tu, size_t nmemb)
if (type->align < builtin_type_uint.align) {
type->align = builtin_type_uint.align;
}
+
+ return nmemb;
}
static void
@@ -423,7 +425,10 @@ tagged_init_from_atype(struct type_store *store,
xcalloc(nmemb, sizeof(struct type_tagged_union *));
size_t i = 0;
collect_atagged_memb(store, tu, &atype->tagged_union, &i);
- tagged_init(type, tu, nmemb);
+ nmemb = tagged_init(type, tu, nmemb);
+
+ expect(&atype->loc, nmemb > 1,
+ "Cannot create tagged union with a single member");
}
static void
diff --git a/tests/13-tagged.ha b/tests/13-tagged.ha
@@ -57,6 +57,12 @@ fn reduction() void = {
const c: (i8 | i16 | i32) = a;
const d: (i8 | i16 | i8 | i16) = a;
assert(rt::compile(
+ // Cannot reduce to a single member
+ "fn test() void = {
+ let a: (u8 | u8) = 42u8;
+ };"
+ ) != 0);
+ assert(rt::compile(
// Cannot assign from more general type
"fn test() void = {
let a: (i8 | i16 | i32) = 42i8;