aboutsummaryrefslogtreecommitdiff
path: root/src/check_expr.c
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2017-04-30 15:29:46 +0100
committerGinger Bill <bill@gingerbill.org>2017-04-30 15:29:46 +0100
commite63393e3941f43aca0976367d36f22207758e4a1 (patch)
treec8e69d0a0cf816cdc0ea625e77b6c68508abfdca /src/check_expr.c
parent784f3ecf7e427c1d948541f62253d6d2eab9e70d (diff)
Add type assertion for `any`
Diffstat (limited to 'src/check_expr.c')
-rw-r--r--src/check_expr.c56
1 files changed, 31 insertions, 25 deletions
diff --git a/src/check_expr.c b/src/check_expr.c
index c700e7d25..3722652b6 100644
--- a/src/check_expr.c
+++ b/src/check_expr.c
@@ -5583,38 +5583,44 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
return kind;
}
- if (!is_type_union(src)) {
- error_node(o->expr, "Type assertions can only operate on unions");
- o->mode = Addressing_Invalid;
- o->expr = node;
- return kind;
- }
+ if (is_type_union(src)) {
+ bool ok = false;
+ for (isize i = 1; i < bsrc->Record.variant_count; i++) {
+ Entity *f = bsrc->Record.variants[i];
+ if (are_types_identical(f->type, dst)) {
+ ok = true;
+ break;
+ }
+ }
- bool ok = false;
- for (isize i = 1; i < bsrc->Record.variant_count; i++) {
- Entity *f = bsrc->Record.variants[i];
- if (are_types_identical(f->type, dst)) {
- ok = true;
- break;
+ if (!ok) {
+ gbString expr_str = expr_to_string(o->expr);
+ gbString dst_type_str = type_to_string(t);
+ error_node(o->expr, "Cannot type assert `%s` to `%s`", expr_str, dst_type_str);
+ gb_string_free(dst_type_str);
+ gb_string_free(expr_str);
+ o->mode = Addressing_Invalid;
+ o->expr = node;
+ return kind;
}
- }
- if (!ok) {
- gbString expr_str = expr_to_string(o->expr);
- gbString dst_type_str = type_to_string(t);
- error_node(o->expr, "Cannot type assert `%s` to `%s`", expr_str, dst_type_str);
- gb_string_free(dst_type_str);
- gb_string_free(expr_str);
+ add_type_info_type(c, o->type);
+ add_type_info_type(c, t);
+
+ o->type = t;
+ o->mode = Addressing_OptionalOk;
+ } else if (is_type_any(o->type)) {
+ o->type = t;
+ o->mode = Addressing_OptionalOk;
+
+ add_type_info_type(c, o->type);
+ add_type_info_type(c, t);
+ } else {
+ error_node(o->expr, "Type assertions can only operate on unions");
o->mode = Addressing_Invalid;
o->expr = node;
return kind;
}
-
- add_type_info_type(c, o->type);
- add_type_info_type(c, t);
-
- o->type = t;
- o->mode = Addressing_OptionalOk;
case_end;
case_ast_node(ue, UnaryExpr, node);