commit 1e68f9f1ce54c93a10c54735c33cb1e043f82ee7
parent b315aba134db251d9df47c75392ecf2e12531e80
Author: Drew DeVault <sir@cmpwn.com>
Date: Sun, 31 Jan 2021 11:11:01 -0500
Implement tagged union duplicate pruning
Diffstat:
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/type_store.c b/src/type_store.c
@@ -275,7 +275,9 @@ tagged_init(struct type *type, struct type_tagged_union **tu, size_t nmemb)
for (size_t i = 1; i < nmemb; ++i)
for (size_t j = 0; j < i; ++j) {
if (tu[j]->type->id == tu[i]->type->id) {
- assert(0); // TODO: prune
+ memmove(&tu[i], &tu[i + 1], nmemb - i - 1);
+ --nmemb;
+ break;
}
}
diff --git a/tests/13-tagged.ha b/tests/13-tagged.ha
@@ -55,6 +55,7 @@ fn reduction() void = {
const a: (i8 | i16) = 42i8;
const b: (i16 | i8) = a;
const c: (i8 | i16 | i32) = a;
+ const d: (i8 | i16 | i8 | i16) = a;
assert(rt::compile(
// Cannot assign from more general type
"fn test() void = {
@@ -62,7 +63,7 @@ fn reduction() void = {
let b: (i8 | i16) = a;
};"
) != 0);
- assert(a is i8 && b is i8 && c is i8);
+ assert(a is i8 && b is i8 && c is i8 && d is i8);
assert(size((i8 | i16 | i32)) == size((i8 | (i16 | i32))));
assert(size(integer) == size(signed));
assert(size(integer) != size((signed | unsigned)));