Browse Source

Fix type cycle bug

gingerBill 7 years ago
parent
commit
5bf0f9d630
8 changed files with 83 additions and 41 deletions
  1. 17 3
      src/check_decl.cpp
  2. 3 1
      src/check_expr.cpp
  3. 4 2
      src/check_stmt.cpp
  4. 22 13
      src/check_type.cpp
  5. 1 0
      src/checker.cpp
  6. 1 0
      src/checker.hpp
  7. 34 16
      src/entity.cpp
  8. 1 6
      src/types.cpp

+ 17 - 3
src/check_decl.cpp

@@ -864,13 +864,21 @@ void check_proc_group_decl(Checker *c, Entity *pg_entity, DeclInfo *d) {
 }
 }
 
 
 void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
 void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
-	if (e->type != nullptr) {
+	if (e->state == EntityState_Resolved)  {
+		return;
+	}
+	String name = e->token.string;
+
+	if (e->type != nullptr || e->state != EntityState_Unresolved) {
+		error(e->token, "Illegal declaration cycle of `%.*s`", LIT(name));
 		return;
 		return;
 	}
 	}
 
 
+	GB_ASSERT(e->state == EntityState_Unresolved);
+
 #if 0
 #if 0
 	char buf[256] = {};
 	char buf[256] = {};
-	isize n = gb_snprintf(buf, 256, "%.*s %d", LIT(e->token.string), e->kind);
+	isize n = gb_snprintf(buf, 256, "%.*s %d", LIT(name), e->kind);
 	Timings timings = {};
 	Timings timings = {};
 	timings_init(&timings, make_string(cast(u8 *)buf, n-1), 16);
 	timings_init(&timings, make_string(cast(u8 *)buf, n-1), 16);
 	defer ({
 	defer ({
@@ -887,17 +895,21 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
 		if (d == nullptr) {
 		if (d == nullptr) {
 			// TODO(bill): Err here?
 			// TODO(bill): Err here?
 			e->type = t_invalid;
 			e->type = t_invalid;
+			e->state = EntityState_Resolved;
 			set_base_type(named_type, t_invalid);
 			set_base_type(named_type, t_invalid);
 			return;
 			return;
-			// GB_PANIC("'%.*s' should been declared!", LIT(e->token.string));
+			// GB_PANIC("'%.*s' should been declared!", LIT(name));
 		}
 		}
 	}
 	}
 
 
 	CheckerContext prev = c->context;
 	CheckerContext prev = c->context;
 	c->context.scope = d->scope;
 	c->context.scope = d->scope;
 	c->context.decl  = d;
 	c->context.decl  = d;
+	c->context.type_level = 0;
 
 
 	e->parent_proc_decl = c->context.curr_proc_decl;
 	e->parent_proc_decl = c->context.curr_proc_decl;
+	e->state = EntityState_InProgress;
+
 
 
 	switch (e->kind) {
 	switch (e->kind) {
 	case Entity_Variable:
 	case Entity_Variable:
@@ -918,6 +930,8 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type) {
 		break;
 		break;
 	}
 	}
 
 
+	e->state = EntityState_Resolved;
+
 	c->context = prev;
 	c->context = prev;
 
 
 #undef TIME_SECTION
 #undef TIME_SECTION

+ 3 - 1
src/check_expr.cpp

@@ -984,7 +984,9 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type *
 	}
 	}
 
 
 	add_entity_use(c, n, e);
 	add_entity_use(c, n, e);
-	check_entity_decl(c, e, nullptr, named_type);
+	if (e->state == EntityState_Unresolved) {
+		check_entity_decl(c, e, nullptr, named_type);
+	}
 
 
 
 
 	if (e->type == nullptr) {
 	if (e->type == nullptr) {

+ 4 - 2
src/check_stmt.cpp

@@ -1000,7 +1000,7 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
 
 
 		check_open_scope(c, stmt);
 		check_open_scope(c, stmt);
 		{
 		{
-			Entity *tag_var = make_entity_variable(c->allocator, c->context.scope, lhs->Ident.token, case_type, false);
+			Entity *tag_var = make_entity_variable(c->allocator, c->context.scope, lhs->Ident.token, case_type, false, EntityState_Resolved);
 			tag_var->flags |= EntityFlag_Used;
 			tag_var->flags |= EntityFlag_Used;
 			tag_var->flags |= EntityFlag_Value;
 			tag_var->flags |= EntityFlag_Value;
 			add_entity(c, c->context.scope, lhs, tag_var);
 			add_entity(c, c->context.scope, lhs, tag_var);
@@ -1467,7 +1467,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 				}
 				}
 				if (found == nullptr) {
 				if (found == nullptr) {
 					bool is_immutable = true;
 					bool is_immutable = true;
-					entity = make_entity_variable(c->allocator, c->context.scope, token, type, is_immutable);
+					entity = make_entity_variable(c->allocator, c->context.scope, token, type, is_immutable, EntityState_Resolved);
 					add_entity_definition(&c->info, name, entity);
 					add_entity_definition(&c->info, name, entity);
 				} else {
 				} else {
 					TokenPos pos = found->token.pos;
 					TokenPos pos = found->token.pos;
@@ -1858,8 +1858,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
 				}
 				}
 				e->flags |= EntityFlag_Visited;
 				e->flags |= EntityFlag_Visited;
 
 
+				e->state = EntityState_InProgress;
 				if (e->type == nullptr) {
 				if (e->type == nullptr) {
 					e->type = init_type;
 					e->type = init_type;
+					e->state = EntityState_Resolved;
 				}
 				}
 				ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
 				ac.link_name = handle_link_name(c, e->token, ac.link_name, ac.link_prefix);
 				e->Variable.thread_local_model = ac.thread_local_model;
 				e->Variable.thread_local_model = ac.thread_local_model;

+ 22 - 13
src/check_type.cpp

@@ -312,6 +312,7 @@ void add_polymorphic_struct_entity(Checker *c, AstNode *node, Type *named_type,
 		node->Ident.token = token;
 		node->Ident.token = token;
 
 
 		e = make_entity_type_name(a, s, token, named_type);
 		e = make_entity_type_name(a, s, token, named_type);
+		e->state = EntityState_Resolved;
 		add_entity_use(c, node, e);
 		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);
 					add_entity(c, scope, name, e);
 					array_add(&entities, 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);
 		Entity *e = make_entity_constant(c->allocator, c->context.scope, ident->Ident.token, constant_type, iota);
 		e->identifier = ident;
 		e->identifier = ident;
 		e->flags |= EntityFlag_Visited;
 		e->flags |= EntityFlag_Visited;
+		e->state = EntityState_Resolved;
 
 
 		HashKey key = hash_string(name);
 		HashKey key = hash_string(name);
 		if (map_get(&entity_map, key) != nullptr) {
 		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;
 						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;
 				param->TypeName.is_type_alias = true;
 			} else {
 			} else {
 				if (operands != nullptr && variables.count < operands->count) {
 				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) {
 			if (p->flags&FieldFlag_no_alias) {
 				param->flags |= EntityFlag_NoAlias;
 				param->flags |= EntityFlag_NoAlias;
 			}
 			}
+			param->state = EntityState_Resolved; // NOTE(bill): This should have be resolved whilst determining it
 
 
 			add_entity(c, scope, name, param);
 			add_entity(c, scope, name, param);
 			array_add(&variables, 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);
 	Scope *s = create_scope(universal_scope, a);
 
 
 	auto fields = array_make<Entity *>(a, 0, 3);
 	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;
 	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);
 	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;
 	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);
 	case_ast_node(i, Ident, e);
 
 
 		Operand o = {};
 		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;
 		gbString err_str = nullptr;
 		defer (gb_string_free(err_str));
 		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)) {
 				if (t != nullptr && is_type_polymorphic_struct_unspecialized(t)) {
 					err_str = expr_to_string(e);
 					err_str = expr_to_string(e);
 					error(e, "Invalid use of a non-specialized polymorphic type '%s'", err_str);
 					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;
 			return true;
 		}
 		}
 
 
@@ -1895,8 +1904,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
 		Token token = ident->Ident.token;
 		Token token = ident->Ident.token;
 		Type *specific = nullptr;
 		Type *specific = nullptr;
 		if (pt->specialization != 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;
 			c->context.in_polymorphic_specialization = true;
 
 
 			AstNode *s = pt->specialization;
 			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);
 			Entity *e = make_entity_type_name(c->allocator, entity_scope, token, t);
 			e->TypeName.is_type_alias = true;
 			e->TypeName.is_type_alias = true;
+			e->state = EntityState_Resolved;
 			add_entity(c, ps, ident, e);
 			add_entity(c, ps, ident, e);
 			add_entity(c, s, ident, e);
 			add_entity(c, s, ident, e);
 		} else {
 		} else {
@@ -2007,9 +2016,9 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
 	case_end;
 	case_end;
 
 
 	case_ast_node(st, StructType, e);
 	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.in_polymorphic_specialization = false;
+		c->context.type_level += 1;
 
 
 		*type = make_type_struct(c->allocator);
 		*type = make_type_struct(c->allocator);
 		set_base_type(named_type, *type);
 		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_end;
 
 
 	case_ast_node(ut, UnionType, e);
 	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.in_polymorphic_specialization = false;
+		c->context.type_level += 1;
 
 
 		*type = make_type_union(c->allocator);
 		*type = make_type_union(c->allocator);
 		set_base_type(named_type, *type);
 		set_base_type(named_type, *type);

+ 1 - 0
src/checker.cpp

@@ -503,6 +503,7 @@ Entity *add_global_entity(Entity *entity) {
 	if (scope_insert_entity(universal_scope, entity)) {
 	if (scope_insert_entity(universal_scope, entity)) {
 		compiler_error("double declaration");
 		compiler_error("double declaration");
 	}
 	}
+	entity->state = EntityState_Resolved;
 	return entity;
 	return entity;
 }
 }
 
 

+ 1 - 0
src/checker.hpp

@@ -268,6 +268,7 @@ struct CheckerContext {
 	DeclInfo * decl;
 	DeclInfo * decl;
 	u32        stmt_state_flags;
 	u32        stmt_state_flags;
 	bool       in_defer; // TODO(bill): Actually handle correctly
 	bool       in_defer; // TODO(bill): Actually handle correctly
+	isize      type_level; // TODO(bill): Actually handle correctly
 	String     proc_name;
 	String     proc_name;
 	Type *     type_hint;
 	Type *     type_hint;
 	DeclInfo * curr_proc_decl;
 	DeclInfo * curr_proc_decl;

+ 34 - 16
src/entity.cpp

@@ -57,25 +57,32 @@ enum OverloadKind {
 	Overload_Yes     = 2,
 	Overload_Yes     = 2,
 };
 };
 
 
+enum EntityState {
+	EntityState_Unresolved = 0,
+	EntityState_InProgress  = 1,
+	EntityState_Resolved   = 2,
+};
+
 
 
 // An Entity is a named "thing" in the language
 // An Entity is a named "thing" in the language
 struct Entity {
 struct Entity {
-	EntityKind kind;
-	u64        id;
-	u32        flags;
-	Token      token;
-	Scope *    scope;
-	Type *     type;
-	AstNode *  identifier; // Can be nullptr
-	DeclInfo * decl_info;
-	DeclInfo * parent_proc_decl; // nullptr if in file/global scope
+	EntityKind  kind;
+	u64         id;
+	u32         flags;
+	EntityState state;
+	Token       token;
+	Scope *     scope;
+	Type *      type;
+	AstNode *   identifier; // Can be nullptr
+	DeclInfo *  decl_info;
+	DeclInfo *  parent_proc_decl; // nullptr if in file/global scope
 
 
 	// TODO(bill): Cleanup how `using` works for entities
 	// TODO(bill): Cleanup how `using` works for entities
-	Entity *   using_parent;
-	AstNode *  using_expr;
+	Entity *    using_parent;
+	AstNode *   using_expr;
 
 
-	isize      order_in_src;
-	String     deprecated_message;
+	isize       order_in_src;
+	String      deprecated_message;
 
 
 	union {
 	union {
 		struct {
 		struct {
@@ -173,6 +180,7 @@ gb_global u64 global_entity_id = 0;
 Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
 Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) {
 	Entity *entity = gb_alloc_item(a, Entity);
 	Entity *entity = gb_alloc_item(a, Entity);
 	entity->kind   = kind;
 	entity->kind   = kind;
+	entity->state  = EntityState_Unresolved;
 	entity->scope  = scope;
 	entity->scope  = scope;
 	entity->token  = token;
 	entity->token  = token;
 	entity->type   = type;
 	entity->type   = type;
@@ -180,9 +188,10 @@ Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token,
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type, bool is_immutable) {
+Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type, bool is_immutable, EntityState state = EntityState_Unresolved) {
 	Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type);
 	Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type);
 	entity->Variable.is_immutable = is_immutable;
 	entity->Variable.is_immutable = is_immutable;
+	entity->state = state;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -194,6 +203,7 @@ Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, T
 	entity->parent_proc_decl = parent->parent_proc_decl;
 	entity->parent_proc_decl = parent->parent_proc_decl;
 	entity->flags |= EntityFlag_Using;
 	entity->flags |= EntityFlag_Using;
 	entity->flags |= EntityFlag_Used;
 	entity->flags |= EntityFlag_Used;
+	entity->state = EntityState_Resolved;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -204,8 +214,9 @@ Entity *make_entity_constant(gbAllocator a, Scope *scope, Token token, Type *typ
 	return entity;
 	return entity;
 }
 }
 
 
-Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type) {
+Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type, EntityState state = EntityState_Unresolved) {
 	Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type);
 	Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type);
+	entity->state = state;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -214,6 +225,7 @@ Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type,
 	Entity *entity = make_entity_variable(a, scope, token, type, is_immutable);
 	Entity *entity = make_entity_variable(a, scope, token, type, is_immutable);
 	entity->flags |= EntityFlag_Used;
 	entity->flags |= EntityFlag_Used;
 	entity->flags |= EntityFlag_Param;
 	entity->flags |= EntityFlag_Param;
+	entity->state = EntityState_Resolved;
 	if (is_using) entity->flags |= EntityFlag_Using;
 	if (is_using) entity->flags |= EntityFlag_Using;
 	if (is_value) entity->flags |= EntityFlag_Value;
 	if (is_value) entity->flags |= EntityFlag_Value;
 	return entity;
 	return entity;
@@ -229,12 +241,13 @@ Entity *make_entity_const_param(gbAllocator a, Scope *scope, Token token, Type *
 }
 }
 
 
 
 
-Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index) {
+Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index, EntityState state = EntityState_Unresolved) {
 	Entity *entity = make_entity_variable(a, scope, token, type, false);
 	Entity *entity = make_entity_variable(a, scope, token, type, false);
 	entity->Variable.field_src_index = field_src_index;
 	entity->Variable.field_src_index = field_src_index;
 	entity->Variable.field_index = field_src_index;
 	entity->Variable.field_index = field_src_index;
 	if (is_using) entity->flags |= EntityFlag_Using;
 	if (is_using) entity->flags |= EntityFlag_Using;
 	entity->flags |= EntityFlag_Field;
 	entity->flags |= EntityFlag_Field;
+	entity->state = state;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -244,6 +257,7 @@ Entity *make_entity_array_elem(gbAllocator a, Scope *scope, Token token, Type *t
 	entity->Variable.field_index = field_src_index;
 	entity->Variable.field_index = field_src_index;
 	entity->flags |= EntityFlag_Field;
 	entity->flags |= EntityFlag_Field;
 	entity->flags |= EntityFlag_ArrayElem;
 	entity->flags |= EntityFlag_ArrayElem;
+	entity->state = EntityState_Resolved;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -262,6 +276,7 @@ Entity *make_entity_proc_group(gbAllocator a, Scope *scope, Token token, Type *t
 Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, i32 id) {
 Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, i32 id) {
 	Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type);
 	Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type);
 	entity->Builtin.id = id;
 	entity->Builtin.id = id;
+	entity->state = EntityState_Resolved;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -277,6 +292,7 @@ Entity *make_entity_import_name(gbAllocator a, Scope *scope, Token token, Type *
 	entity->ImportName.path = path;
 	entity->ImportName.path = path;
 	entity->ImportName.name = name;
 	entity->ImportName.name = name;
 	entity->ImportName.scope = import_scope;
 	entity->ImportName.scope = import_scope;
+	entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
 	return entity;
 	return entity;
 }
 }
 
 
@@ -285,6 +301,7 @@ Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type
 	Entity *entity = alloc_entity(a, Entity_LibraryName, scope, token, type);
 	Entity *entity = alloc_entity(a, Entity_LibraryName, scope, token, type);
 	entity->LibraryName.path = path;
 	entity->LibraryName.path = path;
 	entity->LibraryName.name = name;
 	entity->LibraryName.name = name;
+	entity->state = EntityState_Resolved; // TODO(bill): Is this correct?
 	return entity;
 	return entity;
 }
 }
 
 
@@ -301,6 +318,7 @@ Entity *make_entity_label(gbAllocator a, Scope *scope, Token token, Type *type,
                           AstNode *node) {
                           AstNode *node) {
 	Entity *entity = alloc_entity(a, Entity_Label, scope, token, type);
 	Entity *entity = alloc_entity(a, Entity_Label, scope, token, type);
 	entity->Label.node = node;
 	entity->Label.node = node;
+	entity->state = EntityState_Resolved;
 	return entity;
 	return entity;
 }
 }
 
 

+ 1 - 6
src/types.cpp

@@ -217,6 +217,7 @@ struct Type {
 };
 };
 
 
 
 
+
 // TODO(bill): Should I add extra information here specifying the kind of selection?
 // TODO(bill): Should I add extra information here specifying the kind of selection?
 // e.g. field, constant, array field, type field, etc.
 // e.g. field, constant, array field, type field, etc.
 struct Selection {
 struct Selection {
@@ -481,12 +482,6 @@ Type *alloc_type(gbAllocator a, TypeKind kind) {
 }
 }
 
 
 
 
-Type *make_type_basic(gbAllocator a, BasicType basic) {
-	Type *t = alloc_type(a, Type_Basic);
-	t->Basic = basic;
-	return t;
-}
-
 Type *make_type_generic(gbAllocator a, Scope *scope, i64 id, String name, Type *specialized) {
 Type *make_type_generic(gbAllocator a, Scope *scope, i64 id, String name, Type *specialized) {
 	Type *t = alloc_type(a, Type_Generic);
 	Type *t = alloc_type(a, Type_Generic);
 	t->Generic.id = id;
 	t->Generic.id = id;