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:
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;
}