diff options
| author | gingerBill <bill@gingerbill.org> | 2018-03-23 15:23:14 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2018-03-23 15:23:14 +0000 |
| commit | 5bf0f9d630f16287f7977bbec1d85af9bcb432cf (patch) | |
| tree | a895fb66bc86417e3f70578cbe45218ac265464a /src/check_type.cpp | |
| parent | fff4ead96ab7cab8091f990e6a947a08a23fd3a4 (diff) | |
Fix type cycle bug
Diffstat (limited to 'src/check_type.cpp')
| -rw-r--r-- | src/check_type.cpp | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp index ae6be323f..a999b9807 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -312,6 +312,7 @@ void add_polymorphic_struct_entity(Checker *c, AstNode *node, Type *named_type, node->Ident.token = token; e = make_entity_type_name(a, s, token, named_type); + e->state = EntityState_Resolved; add_entity_use(c, node, e); } @@ -468,6 +469,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera } } + e->state = EntityState_Resolved; add_entity(c, scope, name, e); array_add(&entities, e); } @@ -698,6 +700,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod Entity *e = make_entity_constant(c->allocator, c->context.scope, ident->Ident.token, constant_type, iota); e->identifier = ident; e->flags |= EntityFlag_Visited; + e->state = EntityState_Resolved; HashKey key = hash_string(name); if (map_get(&entity_map, key) != nullptr) { @@ -1181,7 +1184,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari type = t_invalid; } } - param = make_entity_type_name(c->allocator, scope, name->Ident.token, type); + param = make_entity_type_name(c->allocator, scope, name->Ident.token, type, EntityState_Resolved); param->TypeName.is_type_alias = true; } else { if (operands != nullptr && variables.count < operands->count) { @@ -1212,6 +1215,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari if (p->flags&FieldFlag_no_alias) { param->flags |= EntityFlag_NoAlias; } + param->state = EntityState_Resolved; // NOTE(bill): This should have be resolved whilst determining it add_entity(c, scope, name, param); array_add(&variables, param); @@ -1754,9 +1758,9 @@ void generate_map_entry_type(gbAllocator a, Type *type) { Scope *s = create_scope(universal_scope, a); auto fields = array_make<Entity *>(a, 0, 3); - array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("key")), t_map_key, false, 0)); - array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("next")), t_int, false, 1)); - array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("value")), type->Map.value, false, 2)); + array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("key")), t_map_key, false, 0, EntityState_Resolved)); + array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("next")), t_int, false, 1, EntityState_Resolved)); + array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("value")), type->Map.value, false, 2, EntityState_Resolved)); entry_type->Struct.fields = fields; @@ -1793,8 +1797,8 @@ void generate_map_internal_types(gbAllocator a, Type *type) { auto fields = array_make<Entity *>(a, 0, 2); - array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")), hashes_type, false, 0)); - array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1)); + array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("hashes")), hashes_type, false, 0, EntityState_Resolved)); + array_add(&fields, make_entity_field(a, s, make_token_ident(str_lit("entries")), entries_type, false, 1, EntityState_Resolved)); generated_struct_type->Struct.fields = fields; @@ -1842,7 +1846,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) case_ast_node(i, Ident, e); Operand o = {}; - check_ident(c, &o, e, named_type, nullptr, false); + Entity *entity = check_ident(c, &o, e, named_type, nullptr, false); gbString err_str = nullptr; defer (gb_string_free(err_str)); @@ -1857,8 +1861,13 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) if (t != nullptr && is_type_polymorphic_struct_unspecialized(t)) { err_str = expr_to_string(e); error(e, "Invalid use of a non-specialized polymorphic type '%s'", err_str); + return true; } } + + if (c->context.type_level == 0 && entity->state == EntityState_InProgress) { + error(e, "Illegal declaration cycle of `%.*s`", LIT(entity->token.string)); + } return true; } @@ -1895,8 +1904,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) Token token = ident->Ident.token; Type *specific = nullptr; if (pt->specialization != nullptr) { - auto prev_ips = c->context.in_polymorphic_specialization; - defer (c->context.in_polymorphic_specialization = prev_ips); + CheckerContext prev = c->context; defer (c->context = prev); c->context.in_polymorphic_specialization = true; AstNode *s = pt->specialization; @@ -1919,6 +1927,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) } Entity *e = make_entity_type_name(c->allocator, entity_scope, token, t); e->TypeName.is_type_alias = true; + e->state = EntityState_Resolved; add_entity(c, ps, ident, e); add_entity(c, s, ident, e); } else { @@ -2007,9 +2016,9 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) case_end; case_ast_node(st, StructType, e); - bool ips = c->context.in_polymorphic_specialization; - defer (c->context.in_polymorphic_specialization = ips); + CheckerContext prev = c->context; defer (c->context = prev); c->context.in_polymorphic_specialization = false; + c->context.type_level += 1; *type = make_type_struct(c->allocator); set_base_type(named_type, *type); @@ -2021,9 +2030,9 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type) case_end; case_ast_node(ut, UnionType, e); - bool ips = c->context.in_polymorphic_specialization; - defer (c->context.in_polymorphic_specialization = ips); + CheckerContext prev = c->context; defer (c->context = prev); c->context.in_polymorphic_specialization = false; + c->context.type_level += 1; *type = make_type_union(c->allocator); set_base_type(named_type, *type); |