commit c77ca2f0b265f4421cacedd6b10fce3e6adb8515
parent ba423ce6f0a2692e2105645b05b2beb09c061c28
Author: Eyal Sawady <ecs@d2evs.net>
Date: Wed, 11 Aug 2021 07:19:41 +0000
gen: fix nested match with aliases
In this case:
type t = (void | int);
fn foo() void = {
let x: (t | int) = 10;
match (x) {
(void | int) => void,
int => void,
};
};
we wouldn't exit the loop on test == t because it doesn't have the same
id as (void | int). Rather than just testing against t, test against
type_dealias(t) as well.
We don't want to dealias _case->type, because that can lead to false
positives. For example, in this case:
type foo = void;
type bar = void;
fn foo() void = {
match (foo) {
bar => void,
foo => void,
};
};
we need to avoid matching with bar.
This issue was causing 18-match to fail, now that it's fixed, enable
that test.
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/gen.c b/src/gen.c
@@ -1638,7 +1638,8 @@ gen_nested_match_tests(struct gen_context *ctx, struct gen_value object,
pushi(ctx->current, NULL, Q_JNZ, &match, &bsubtype, &bnext, NULL);
push(&ctx->current->body, &lsubtype);
- if (test->id != _case->type->id) {
+ if (test->id != _case->type->id
+ && type_dealias(test)-> id != _case->type->id) {
struct qbe_value offs = constl(subtype->align);
pushi(ctx->current, &subval, Q_ADD, &subval, &offs, NULL);
pushi(ctx->current, &temp, Q_LOADUW, &subval, NULL);
@@ -1647,7 +1648,8 @@ gen_nested_match_tests(struct gen_context *ctx, struct gen_value object,
}
subtype = test;
- } while (test->id != _case->type->id);
+ } while (test->id != _case->type->id
+ && type_dealias(test)->id != _case->type->id);
pushi(ctx->current, NULL, Q_JMP, &bmatch, NULL);
}
diff --git a/tests/configure b/tests/configure
@@ -57,6 +57,7 @@ EOF
15-enums \
16-defer \
17-alloc \
+ 18-match \
19-append \
20-if \
24-imports \
@@ -66,7 +67,6 @@ EOF
29-unarithm
# Disabled tests
- #18-match \
#21-tuples \
#22-delete \
#23-errors \