diff options
-rw-r--r-- | identifiers.c | 3 | ||||
-rw-r--r-- | parse.c | 7 | ||||
-rw-r--r-- | types.c | 32 |
3 files changed, 29 insertions, 13 deletions
diff --git a/identifiers.c b/identifiers.c index d86dba1..a9b4540 100644 --- a/identifiers.c +++ b/identifiers.c @@ -177,8 +177,7 @@ static void idents_test(void) { idents_free(&ids); } - -static inline Type *ident_typeval(Identifier i) { +static Type *ident_typeval(Identifier i) { Value *val; IdentDecl *idecl = ident_decl(i); if (!idecl) return NULL; @@ -1973,3 +1973,10 @@ static long decl_ident_index(Declaration *d, Identifier i) { } return -1; } + +static Value *decl_ident_val(Declaration *d, Identifier i) { + if (d->type.kind == TYPE_TUPLE) + return &d->val.tuple[decl_ident_index(d, i)]; + else + return &d->val; +} @@ -362,21 +362,31 @@ static bool type_resolve(Typer *tr, Type *t, Location where) { if (!type_resolve(tr, t->slice, where)) return false; break; - case TYPE_USER: - /* just check if it's actually defined */ - if (!ident_typeval(t->user.name)) { + case TYPE_USER: { + /* check if it's actually defined */ + IdentDecl *idecl = ident_decl(t->user.name); + if (!idecl) { char *s = ident_to_str(t->user.name); - IdentDecl *idecl = ident_decl(t->user.name); - if (idecl) { - err_print(where, "Use of non-type identifier %s as type.", s); - info_print(idecl->decl->where, "%s is declared here.", s); - } else { - err_print(where, "Use of undeclared type %s.", s); - } + err_print(where, "Use of undeclared type %s.", s); free(s); return false; } - break; + Declaration *decl = idecl->decl; + /* now, type the declaration (in case we are using it before its declaration) */ + if (!types_decl(tr, decl)) + return false; + /* make sure it's actually a type */ + if (idecl->decl->type.kind != TYPE_TYPE) { + char *s = ident_to_str(t->user.name); + err_print(where, "Use of non-type identifier %s as type.", s); + info_print(decl->where, "%s is declared here.", s); + free(s); + return s; + } + /* resolve inner type */ + Value *val = decl_ident_val(decl, t->user.name); + if (!type_resolve(tr, val->type, decl->where)) return false; + } break; case TYPE_STRUCT: arr_foreach(t->struc.fields, Field, f) { if (!type_resolve(tr, f->type, where)) |