aboutsummaryrefslogtreecommitdiff
path: root/src/typecheck.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-12-06 14:55:00 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-12-06 14:55:00 -0500
commit48491f94c96615e8055bcf72ed9009b1d921467f (patch)
treeb30b934d71ca14a7f9602282c35d2f2c137d902a /src/typecheck.c
parenta13b39f1e1ea220a868d99508796d06492a40611 (diff)
Use `foo!` as sugar for `foo.FirstTag!` for enum values. Also, give
better error messages for this kind of `!` assertion.
Diffstat (limited to 'src/typecheck.c')
-rw-r--r--src/typecheck.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/typecheck.c b/src/typecheck.c
index 6f8fa0ba..41de1a6b 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -755,7 +755,12 @@ type_t *get_type(env_t *env, ast_t *ast) {
}
case NonOptional: {
ast_t *value = Match(ast, NonOptional)->value;
- type_t *t = get_type(env, value);
+ type_t *t = value_type(get_type(env, value));
+ if (t->tag == EnumType) {
+ tag_t *first_tag = Match(t, EnumType)->tags;
+ if (!first_tag) code_err(ast, "'!' cannot be used on an empty enum");
+ return first_tag->type;
+ }
if (t->tag != OptionalType)
code_err(value, "This value is not optional. Only optional values can use the '!' operator.");
return Match(t, OptionalType)->type;
@@ -1539,7 +1544,10 @@ PUREFUNC bool is_discardable(env_t *env, ast_t *ast) {
default: break;
}
type_t *t = get_type(env, ast);
- return (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType || t == EMPTY_TYPE);
+ if (t->tag == StructType) {
+ return (Match(t, StructType)->fields == NULL);
+ }
+ return (t->tag == VoidType || t->tag == AbortType || t->tag == ReturnType);
}
type_t *get_arg_ast_type(env_t *env, arg_ast_t *arg) {