harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit a2429ed9053bf5e78aa7dbd707abaf092f4252d4
parent 146eaad1d72119c443c934a97f8913584d172885
Author: Eyal Sawady <ecs@d2evs.net>
Date:   Sat,  4 Sep 2021 07:17:09 +0000

result reduction: merge `type` with `const type`

Signed-off-by: Eyal Sawady <ecs@d2evs.net>

Diffstat:
Msrc/type_store.c | 17+++++++++++++++++
Mtests/30-reduction.c | 10++++++++++
2 files changed, 27 insertions(+), 0 deletions(-)

diff --git a/src/type_store.c b/src/type_store.c @@ -975,6 +975,7 @@ type_store_lookup_tuple(struct type_store *store, struct type_tuple *values) // Algorithm: // - Deduplicate and collect nested unions // - Merge *type with nullable *type +// - Merge type with const type // - If one of the types is null: // - If there's more than one pointer type, error out // - If there's one pointer type, make it nullable and drop the null @@ -1002,6 +1003,22 @@ type_store_reduce_result(struct type_store *store, struct type_tagged_union *in) struct type_tagged_union *i = *tu; bool dropped = false; const struct type *it = i->type; + + if (it->flags && TYPE_CONST) { + for (struct type_tagged_union **j = &in; *j; + j = &(*j)->next) { + const struct type *jt = (*j)->type; + if (jt == it) { + continue; + } + jt = type_store_lookup_with_flags(store, jt, + jt->flags | TYPE_CONST); + if (jt == it) { + *j = (*j)->next; + } + } + } + for (struct type_tagged_union *j = in; j != i; j = j->next) { const struct type *jt = j->type; assert(it->id != jt->id); diff --git a/tests/30-reduction.c b/tests/30-reduction.c @@ -103,6 +103,16 @@ int main(void) { test(&ctx, "(*int | const nullable *int)", "if (true) null: *int " "else null: const nullable *int"); + test(&ctx, "const rune", + "if (true) 'a' " + "else 'a': const rune"); + test(&ctx, "const rune", + "if (true) 'a': const rune " + "else 'a'"); + test(&ctx, "(*int | const nullable *int)", + "if (true) null: *int " + "else if (true) null: const nullable *int " + "else null: nullable *int"); test(&ctx, "", "if (true) null "