commit 697e1d64a0f57290f7fd3eebc548cd2f19830ef5
parent ae4c3c71a23f1b9d496c106a43aa434b2b0562f4
Author: Drew DeVault <sir@cmpwn.com>
Date: Sat, 16 Jan 2021 11:05:34 -0500
Implement type alias unwrapping
Diffstat:
4 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/include/ast.h b/include/ast.h
@@ -90,7 +90,6 @@ struct ast_type {
enum type_storage storage;
unsigned int flags;
union {
- struct identifier alias;
struct ast_list_type array;
struct ast_enum_type _enum;
struct ast_function_type func;
@@ -98,6 +97,10 @@ struct ast_type {
struct ast_list_type slice;
struct ast_struct_union_type struct_union;
struct ast_tagged_union_type tagged_union;
+ struct {
+ struct identifier alias;
+ bool unwrap;
+ };
};
};
diff --git a/src/parse.c b/src/parse.c
@@ -549,8 +549,7 @@ parse_type(struct lexer *lexer)
break;
}
struct ast_type *type = NULL;
- bool noreturn = false;
- bool nullable = false;
+ bool noreturn = false, nullable = false, unwrap = false;
switch (lex(lexer, &tok)) {
case T_I8:
case T_I16:
@@ -632,10 +631,15 @@ parse_type(struct lexer *lexer)
type->func.flags |= FN_NORETURN;
}
break;
+ case T_ELLIPSIS:
+ unwrap = true;
+ want(lexer, T_NAME, &tok);
+ // Fallthrough
case T_NAME:
unlex(lexer, &tok);
type = mktype(&lexer->loc);
type->storage = TYPE_STORAGE_ALIAS;
+ type->unwrap = unwrap;
parse_identifier(lexer, &type->alias);
break;
default:
diff --git a/src/type_store.c b/src/type_store.c
@@ -537,8 +537,11 @@ type_init_from_atype(struct type_store *store,
assert(0); // Invariant
case TYPE_STORAGE_ALIAS:
obj = scope_lookup(store->check_context->scope, &atype->alias);
- // TODO: Bubble this up:
- assert(obj && obj->otype == O_TYPE);
+ if (atype->unwrap) {
+ *type = *obj->type;
+ break;
+ }
+ assert(obj && obj->otype == O_TYPE); // TODO: Bubble this up
identifier_dup(&type->alias.ident, &atype->alias);
type->alias.type = obj->type;
type->size = type->alias.type->size;
diff --git a/tests/07-aliases.ha b/tests/07-aliases.ha
@@ -6,6 +6,11 @@ fn alias_builtin() void = {
assert(i == 1234: my_int, "built-in alias");
};
+fn unwrap() void = {
+ let i: ...my_int = 1234;
+ assert(i == 1234);
+};
+
type my_array = [3]int;
type my_array_ptr = *my_array;
type my_array_ptr_ptr = *my_array_ptr;