harec

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

commit abd2a236e806b555c6207bb60adc83c1f618976c
parent 6b581cdc69c986da8e21abae344dbb94dba97772
Author: Drew DeVault <sir@cmpwn.com>
Date:   Tue, 23 Feb 2021 11:41:18 -0500

Fix various issues with flag handling and types

1. There are no built-in error types, handle that accordingly
2. Type aliases shall always inherit the flags of their original
   definition, such that the following:

   type foo = const int;
   let x: foo = 10;

   Does not lose the const flag.

The second issue may require a spec update and likely inherits issues
related to forward-declaration of type aliases.

Diffstat:
Msrc/check.c | 6++----
Msrc/type_store.c | 44++++++++++++++++++++++++++++++++++++++++----
2 files changed, 42 insertions(+), 8 deletions(-)

diff --git a/src/check.c b/src/check.c @@ -412,10 +412,8 @@ type_promote(struct type_store *store, const struct type *_b) { bool is_const = (_a->flags & TYPE_CONST) || (_b->flags & TYPE_CONST); - const struct type *a = - type_store_lookup_with_flags(store, _a, _a->flags & ~TYPE_CONST); - const struct type *b = - type_store_lookup_with_flags(store, _b, _b->flags & ~TYPE_CONST); + const struct type *a = type_store_lookup_with_flags(store, _a, 0); + const struct type *b = type_store_lookup_with_flags(store, _b, 0); if (a->storage == STORAGE_ALIAS) { return a == b || a->alias.type == b ? _b : NULL; diff --git a/src/type_store.c b/src/type_store.c @@ -92,6 +92,9 @@ builtin_type_for_storage(enum type_storage storage, bool is_const) static const struct type * builtin_for_atype(const struct ast_type *atype) { + if (atype->flags & TYPE_ERROR) { + return NULL; + } bool is_const = (atype->flags & TYPE_CONST) != 0; return builtin_type_for_storage(atype->storage, is_const); } @@ -99,6 +102,9 @@ builtin_for_atype(const struct ast_type *atype) static const struct type * builtin_for_type(const struct type *type) { + if (type->flags & TYPE_ERROR) { + return NULL; + } bool is_const = (type->flags & TYPE_CONST) != 0; return builtin_type_for_storage(type->storage, is_const); } @@ -389,18 +395,20 @@ type_init_from_atype(struct type_store *store, const struct scope_object *obj; const struct identifier *ident; + const struct type *builtin; struct identifier temp; switch (type->storage) { + case STORAGE_FCONST: + case STORAGE_ICONST: + assert(0); // Invariant case STORAGE_BOOL: case STORAGE_CHAR: case STORAGE_F32: case STORAGE_F64: - case STORAGE_FCONST: case STORAGE_I8: case STORAGE_I16: case STORAGE_I32: case STORAGE_I64: - case STORAGE_ICONST: case STORAGE_INT: case STORAGE_NULL: case STORAGE_RUNE: @@ -413,7 +421,10 @@ type_init_from_atype(struct type_store *store, case STORAGE_UINT: case STORAGE_UINTPTR: case STORAGE_VOID: - assert(0); // Invariant + builtin = builtin_type_for_storage(type->storage, false); + type->size = builtin->size; + type->align = builtin->align; + break; case STORAGE_ALIAS: ident = &atype->alias; if (ident->ns == NULL) { @@ -576,13 +587,31 @@ type_init_from_atype(struct type_store *store, } static const struct type * -type_store_lookup_type(struct type_store *store, const struct type *type) +_type_store_lookup_type( + struct type_store *store, + const struct type *type, + bool recur) { const struct type *builtin = builtin_for_type(type); if (builtin) { return builtin; } + struct type psuedotype = *type; + if (type->storage == STORAGE_ALIAS && !recur) { + // References to type aliases always inherit the flags that the + // alias was defined with + // + // TODO: This is likely problematic for forward references + // TODO: Does this need a spec update? + const struct scope_object *obj = scope_lookup( + store->check_context->scope, &type->alias.ident); + if (obj) { + psuedotype.flags |= obj->type->flags; + type = &psuedotype; + } + } + uint32_t hash = type_hash(type); struct type_bucket **next = &store->buckets[hash % TYPE_STORE_BUCKETS], *bucket = NULL; @@ -601,6 +630,12 @@ type_store_lookup_type(struct type_store *store, const struct type *type) return &bucket->type; } +static const struct type * +type_store_lookup_type(struct type_store *store, const struct type *type) +{ + return _type_store_lookup_type(store, type, false); +} + const struct type * type_store_lookup_atype(struct type_store *store, const struct ast_type *atype) { @@ -693,6 +728,7 @@ type_store_lookup_alias(struct type_store *store, type->alias.type = secondary; type->size = secondary->size; type->align = secondary->align; + type->flags = secondary->flags; } return type; }