Browse Source

Fix `find_using_index_expr`

Ginger Bill 8 years ago
parent
commit
c2fa79012e
7 changed files with 62 additions and 33 deletions
  1. 1 1
      src/check_decl.c
  2. 9 17
      src/check_expr.c
  3. 7 0
      src/checker.c
  4. 4 4
      src/entity.c
  5. 28 6
      src/ir.c
  6. 2 2
      src/ssa.c
  7. 11 3
      src/types.c

+ 1 - 1
src/check_decl.c

@@ -531,7 +531,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
 		for (isize i = 0; i < params->variable_count; i++) {
 		for (isize i = 0; i < params->variable_count; i++) {
 			Entity *e = params->variables[i];
 			Entity *e = params->variables[i];
 			GB_ASSERT(e->kind == Entity_Variable);
 			GB_ASSERT(e->kind == Entity_Variable);
-			if (!(e->flags & EntityFlag_Anonymous)) {
+			if (!(e->flags & EntityFlag_Using)) {
 				continue;
 				continue;
 			}
 			}
 			bool is_immutable = e->Variable.is_immutable;
 			bool is_immutable = e->Variable.is_immutable;

+ 9 - 17
src/check_expr.c

@@ -89,7 +89,7 @@ bool check_is_assignable_to_using_subtype(Type *dst, Type *src) {
 	if (is_type_struct(src)) {
 	if (is_type_struct(src)) {
 		for (isize i = 0; i < src->Record.field_count; i++) {
 		for (isize i = 0; i < src->Record.field_count; i++) {
 			Entity *f = src->Record.fields[i];
 			Entity *f = src->Record.fields[i];
-			if (f->kind == Entity_Variable && (f->flags & EntityFlag_Anonymous)) {
+			if (f->kind == Entity_Variable && (f->flags & EntityFlag_Using)) {
 				if (are_types_identical(dst, f->type)) {
 				if (are_types_identical(dst, f->type)) {
 					return true;
 					return true;
 				}
 				}
@@ -323,7 +323,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en
 			} else {
 			} else {
 				map_entity_set(entity_map, key, f);
 				map_entity_set(entity_map, key, f);
 				add_entity(c, c->context.scope, NULL, f);
 				add_entity(c, c->context.scope, NULL, f);
-				if (f->flags & EntityFlag_Anonymous) {
+				if (f->flags & EntityFlag_Using) {
 					populate_using_entity_map(c, node, f->type, entity_map);
 					populate_using_entity_map(c, node, f->type, entity_map);
 				}
 				}
 			}
 			}
@@ -406,7 +406,7 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 					bool ok = true;
 					bool ok = true;
 					for_array(emi, entity_map.entries) {
 					for_array(emi, entity_map.entries) {
 						Entity *e = entity_map.entries.e[emi].value;
 						Entity *e = entity_map.entries.e[emi].value;
-						if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
+						if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
 							if (is_type_indexable(e->type)) {
 							if (is_type_indexable(e->type)) {
 								if (e->identifier != f->names.e[0]) {
 								if (e->identifier != f->names.e[0]) {
 									ok = false;
 									ok = false;
@@ -419,7 +419,7 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 					if (ok) {
 					if (ok) {
 						using_index_expr = fields[field_index-1];
 						using_index_expr = fields[field_index-1];
 					} else {
 					} else {
-						fields[field_index-1]->flags &= ~EntityFlag_Anonymous;
+						fields[field_index-1]->flags &= ~EntityFlag_Using;
 						error(name_token, "Previous `using` for an index expression `%.*s`", LIT(name_token.string));
 						error(name_token, "Previous `using` for an index expression `%.*s`", LIT(name_token.string));
 					}
 					}
 				} else {
 				} else {
@@ -603,6 +603,8 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) {
 	union_type->Record.fields_in_src_order = fields;
 	union_type->Record.fields_in_src_order = fields;
 	union_type->Record.field_count         = field_count;
 	union_type->Record.field_count         = field_count;
 	union_type->Record.are_offsets_set     = false;
 	union_type->Record.are_offsets_set     = false;
+	union_type->Record.is_ordered          = true;
+
 
 
 
 
 	for_array(i, ut->variants) {
 	for_array(i, ut->variants) {
@@ -2056,17 +2058,6 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
 		} break;
 		} break;
 		}
 		}
 
 
-	#if 0
-		// CLEANUP(bill) NOTE(bill): there is an auto assignment to `any` which needs to be checked
-		if (is_type_any(x->type) && !is_type_any(y->type)) {
-			err_type = x->type;
-			defined = false;
-		} else if (is_type_any(y->type) && !is_type_any(x->type)) {
-			err_type = y->type;
-			defined = false;
-		}
-	#endif
-
 		if (!defined) {
 		if (!defined) {
 			if (x->type == err_type && is_operand_nil(*x)) {
 			if (x->type == err_type && is_operand_nil(*x)) {
 				err_type = y->type;
 				err_type = y->type;
@@ -2223,7 +2214,7 @@ String check_down_cast_name(Type *dst_, Type *src_) {
 	for (isize i = 0; i < dst_s->Record.field_count; i++) {
 	for (isize i = 0; i < dst_s->Record.field_count; i++) {
 		Entity *f = dst_s->Record.fields[i];
 		Entity *f = dst_s->Record.fields[i];
 		GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
 		GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
-		if (f->flags & EntityFlag_Anonymous) {
+		if (f->flags & EntityFlag_Using) {
 			if (are_types_identical(f->type, src_)) {
 			if (are_types_identical(f->type, src_)) {
 				return f->token.string;
 				return f->token.string;
 			}
 			}
@@ -4705,7 +4696,8 @@ Entity *find_using_index_expr(Type *t) {
 	for (isize i = 0; i < t->Record.field_count; i++) {
 	for (isize i = 0; i < t->Record.field_count; i++) {
 		Entity *f = t->Record.fields[i];
 		Entity *f = t->Record.fields[i];
 		if (f->kind == Entity_Variable &&
 		if (f->kind == Entity_Variable &&
-		    f->flags & (EntityFlag_Anonymous|EntityFlag_Field)) {
+		    (f->flags & EntityFlag_Field) != 0 &&
+		    (f->flags & EntityFlag_Using) != 0) {
 			if (is_type_indexable(f->type)) {
 			if (is_type_indexable(f->type)) {
 				return f;
 				return f;
 			}
 			}

+ 7 - 0
src/checker.c

@@ -1984,6 +1984,8 @@ void check_parsed_files(Checker *c) {
 		}
 		}
 	}
 	}
 
 
+
+
 	// NOTE(bill): Check for illegal cyclic type declarations
 	// NOTE(bill): Check for illegal cyclic type declarations
 	for_array(i, c->info.definitions.entries) {
 	for_array(i, c->info.definitions.entries) {
 		Entity *e = c->info.definitions.entries.e[i].value;
 		Entity *e = c->info.definitions.entries.e[i].value;
@@ -1991,10 +1993,15 @@ void check_parsed_files(Checker *c) {
 			if (e->type != NULL) {
 			if (e->type != NULL) {
 				// i64 size  = type_size_of(c->sizes, c->allocator, e->type);
 				// i64 size  = type_size_of(c->sizes, c->allocator, e->type);
 				i64 align = type_align_of(c->allocator, e->type);
 				i64 align = type_align_of(c->allocator, e->type);
+				if (align > 0) {
+					// add_type_info_type(c, e->type);
+				}
 			}
 			}
 		}
 		}
 	}
 	}
 
 
+	// gb_printf_err("Count: %td\n", c->info.type_info_count++);
+
 	for_array(i, file_scopes.entries) {
 	for_array(i, file_scopes.entries) {
 		Scope *s = file_scopes.entries.e[i].value;
 		Scope *s = file_scopes.entries.e[i].value;
 		if (s->is_init) {
 		if (s->is_init) {

+ 4 - 4
src/entity.c

@@ -33,7 +33,7 @@ String const entity_strings[] = {
 typedef enum EntityFlag {
 typedef enum EntityFlag {
 	EntityFlag_Visited    = 1<<0,
 	EntityFlag_Visited    = 1<<0,
 	EntityFlag_Used       = 1<<1,
 	EntityFlag_Used       = 1<<1,
-	EntityFlag_Anonymous  = 1<<2,
+	EntityFlag_Using      = 1<<2,
 	EntityFlag_Field      = 1<<3,
 	EntityFlag_Field      = 1<<3,
 	EntityFlag_Param      = 1<<4,
 	EntityFlag_Param      = 1<<4,
 	EntityFlag_VectorElem = 1<<5,
 	EntityFlag_VectorElem = 1<<5,
@@ -159,7 +159,7 @@ Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, T
 	token.pos = parent->token.pos;
 	token.pos = parent->token.pos;
 	Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
 	Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type);
 	entity->using_parent = parent;
 	entity->using_parent = parent;
-	entity->flags |= EntityFlag_Anonymous;
+	entity->flags |= EntityFlag_Using;
 	return entity;
 	return entity;
 }
 }
 
 
@@ -178,7 +178,7 @@ Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *ty
 Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool anonymous, bool is_immutable) {
 Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool anonymous, bool is_immutable) {
 	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;
-	if (anonymous) entity->flags |= EntityFlag_Anonymous;
+	if (anonymous) entity->flags |= EntityFlag_Using;
 	entity->flags |= EntityFlag_Param;
 	entity->flags |= EntityFlag_Param;
 	return entity;
 	return entity;
 }
 }
@@ -188,7 +188,7 @@ Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type,
 	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;
 	entity->flags |= EntityFlag_Field;
 	entity->flags |= EntityFlag_Field;
-	entity->flags |= EntityFlag_Anonymous*(anonymous != 0);
+	entity->flags |= EntityFlag_Using*(anonymous != 0);
 	return entity;
 	return entity;
 }
 }
 
 

+ 28 - 6
src/ir.c

@@ -142,6 +142,7 @@ struct irProcedure {
 #define IR_TYPE_INFO_TYPES_NAME      "__$type_info_types_data"
 #define IR_TYPE_INFO_TYPES_NAME      "__$type_info_types_data"
 #define IR_TYPE_INFO_NAMES_NAME      "__$type_info_names_data"
 #define IR_TYPE_INFO_NAMES_NAME      "__$type_info_names_data"
 #define IR_TYPE_INFO_OFFSETS_NAME    "__$type_info_offsets_data"
 #define IR_TYPE_INFO_OFFSETS_NAME    "__$type_info_offsets_data"
+#define IR_TYPE_INFO_USINGS_NAME     "__$type_info_usings_data"
 
 
 
 
 #define IR_INSTR_KINDS \
 #define IR_INSTR_KINDS \
@@ -2596,7 +2597,7 @@ String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
 	GB_ASSERT(is_type_struct(src));
 	GB_ASSERT(is_type_struct(src));
 	for (isize i = 0; i < src->Record.field_count; i++) {
 	for (isize i = 0; i < src->Record.field_count; i++) {
 		Entity *f = src->Record.fields[i];
 		Entity *f = src->Record.fields[i];
-		if (f->kind == Entity_Variable && f->flags & EntityFlag_Anonymous) {
+		if (f->kind == Entity_Variable && f->flags & EntityFlag_Using) {
 			if (are_types_identical(dst, f->type)) {
 			if (are_types_identical(dst, f->type)) {
 				return f->token.string;
 				return f->token.string;
 			}
 			}
@@ -3123,11 +3124,13 @@ gb_global irValue *ir_global_type_info_data           = NULL;
 gb_global irValue *ir_global_type_info_member_types   = NULL;
 gb_global irValue *ir_global_type_info_member_types   = NULL;
 gb_global irValue *ir_global_type_info_member_names   = NULL;
 gb_global irValue *ir_global_type_info_member_names   = NULL;
 gb_global irValue *ir_global_type_info_member_offsets = NULL;
 gb_global irValue *ir_global_type_info_member_offsets = NULL;
+gb_global irValue *ir_global_type_info_member_usings  = NULL;
 
 
 gb_global i32      ir_global_type_info_data_index           = 0;
 gb_global i32      ir_global_type_info_data_index           = 0;
 gb_global i32      ir_global_type_info_member_types_index   = 0;
 gb_global i32      ir_global_type_info_member_types_index   = 0;
 gb_global i32      ir_global_type_info_member_names_index   = 0;
 gb_global i32      ir_global_type_info_member_names_index   = 0;
 gb_global i32      ir_global_type_info_member_offsets_index = 0;
 gb_global i32      ir_global_type_info_member_offsets_index = 0;
+gb_global i32      ir_global_type_info_member_usings_index  = 0;
 
 
 
 
 irValue *ir_type_info(irProcedure *proc, Type *type) {
 irValue *ir_type_info(irProcedure *proc, Type *type) {
@@ -4550,7 +4553,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
 }
 }
 
 
 irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
 irValue *ir_get_using_variable(irProcedure *proc, Entity *e) {
-	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
+	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
 	String name = e->token.string;
 	String name = e->token.string;
 	Entity *parent = e->using_parent;
 	Entity *parent = e->using_parent;
 	Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
 	Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
@@ -4594,7 +4597,7 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) {
 	irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
 	irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e));
 	if (found) {
 	if (found) {
 		v = *found;
 		v = *found;
-	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
+	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
 		// NOTE(bill): Calculate the using variable every time
 		// NOTE(bill): Calculate the using variable every time
 		v = ir_get_using_variable(proc, e);
 		v = ir_get_using_variable(proc, e);
 	}
 	}
@@ -6741,6 +6744,16 @@ void ir_init_module(irModule *m, Checker *c) {
 				map_ir_value_set(&m->members, hash_string(name), g);
 				map_ir_value_set(&m->members, hash_string(name), g);
 				ir_global_type_info_member_offsets = g;
 				ir_global_type_info_member_offsets = g;
 			}
 			}
+
+			{
+				String name = str_lit(IR_TYPE_INFO_USINGS_NAME);
+				Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
+				                                 make_type_array(m->allocator, t_bool, count), false);
+				irValue *g = ir_value_global(m->allocator, e, NULL);
+				ir_module_add_value(m, e, g);
+				map_ir_value_set(&m->members, hash_string(name), g);
+				ir_global_type_info_member_usings = g;
+			}
 		}
 		}
 	}
 	}
 
 
@@ -6832,6 +6845,11 @@ irValue *ir_type_info_member_offsets_offset(irProcedure *proc, isize count) {
 	ir_global_type_info_member_offsets_index += count;
 	ir_global_type_info_member_offsets_index += count;
 	return offset;
 	return offset;
 }
 }
+irValue *ir_type_info_member_usings_offset(irProcedure *proc, isize count) {
+	irValue *offset = ir_emit_array_epi(proc, ir_global_type_info_member_usings, ir_global_type_info_member_usings_index);
+	ir_global_type_info_member_usings_index += count;
+	return offset;
+}
 
 
 
 
 
 
@@ -7393,14 +7411,15 @@ void ir_gen_tree(irGen *s) {
 							irValue *packed       = ir_const_bool(a, t->Record.is_packed);
 							irValue *packed       = ir_const_bool(a, t->Record.is_packed);
 							irValue *ordered      = ir_const_bool(a, t->Record.is_ordered);
 							irValue *ordered      = ir_const_bool(a, t->Record.is_ordered);
 							irValue *custom_align = ir_const_bool(a, t->Record.custom_align);
 							irValue *custom_align = ir_const_bool(a, t->Record.custom_align);
-							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 3), packed);
-							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), ordered);
-							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 5), custom_align);
+							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 4), packed);
+							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 5), ordered);
+							ir_emit_store(proc, ir_emit_struct_ep(proc, record, 6), custom_align);
 						}
 						}
 
 
 						irValue *memory_types   = ir_type_info_member_types_offset(proc, t->Record.field_count);
 						irValue *memory_types   = ir_type_info_member_types_offset(proc, t->Record.field_count);
 						irValue *memory_names   = ir_type_info_member_names_offset(proc, t->Record.field_count);
 						irValue *memory_names   = ir_type_info_member_names_offset(proc, t->Record.field_count);
 						irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, t->Record.field_count);
 						irValue *memory_offsets = ir_type_info_member_offsets_offset(proc, t->Record.field_count);
+						irValue *memory_usings  = ir_type_info_member_usings_offset(proc, t->Record.field_count);
 
 
 						type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
 						type_set_offsets(a, t); // NOTE(bill): Just incase the offsets have not been set yet
 						for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
 						for (isize source_index = 0; source_index < t->Record.field_count; source_index++) {
@@ -7413,6 +7432,7 @@ void ir_gen_tree(irGen *s) {
 							irValue *index     = ir_const_int(a, source_index);
 							irValue *index     = ir_const_int(a, source_index);
 							irValue *type_info = ir_emit_ptr_offset(proc, memory_types,   index);
 							irValue *type_info = ir_emit_ptr_offset(proc, memory_types,   index);
 							irValue *offset    = ir_emit_ptr_offset(proc, memory_offsets, index);
 							irValue *offset    = ir_emit_ptr_offset(proc, memory_offsets, index);
+							irValue *is_using  = ir_emit_ptr_offset(proc, memory_usings, index);
 
 
 							ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
 							ir_emit_store(proc, type_info, ir_type_info(proc, f->type));
 							if (f->token.string.len > 0) {
 							if (f->token.string.len > 0) {
@@ -7420,12 +7440,14 @@ void ir_gen_tree(irGen *s) {
 								ir_emit_store(proc, name, ir_const_string(a, f->token.string));
 								ir_emit_store(proc, name, ir_const_string(a, f->token.string));
 							}
 							}
 							ir_emit_store(proc, offset, ir_const_int(a, foffset));
 							ir_emit_store(proc, offset, ir_const_int(a, foffset));
+							ir_emit_store(proc, is_using, ir_const_bool(a, f->flags&EntityFlag_Using));
 						}
 						}
 
 
 						irValue *count = ir_const_int(a, t->Record.field_count);
 						irValue *count = ir_const_int(a, t->Record.field_count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types,   count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 0), memory_types,   count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names,   count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 1), memory_names,   count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 2), memory_offsets, count, count);
 						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 2), memory_offsets, count, count);
+						ir_fill_slice(proc, ir_emit_struct_ep(proc, record, 3), memory_usings,  count, count);
 					} break;
 					} break;
 					case TypeRecord_Union: {
 					case TypeRecord_Union: {
 						ir_emit_comment(proc, str_lit("Type_Info_Union"));
 						ir_emit_comment(proc, str_lit("Type_Info_Union"));

+ 2 - 2
src/ssa.c

@@ -700,7 +700,7 @@ ssaValue *ssa_addr_load(ssaProc *p, ssaAddr addr) {
 }
 }
 
 
 ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
 ssaValue *ssa_get_using_variable(ssaProc *p, Entity *e) {
-	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous);
+	GB_ASSERT(e->kind == Entity_Variable && e->flags & EntityFlag_Using);
 	String name = e->token.string;
 	String name = e->token.string;
 	Entity *parent = e->using_parent;
 	Entity *parent = e->using_parent;
 	Selection sel = lookup_field(p->allocator, parent->type, name, false);
 	Selection sel = lookup_field(p->allocator, parent->type, name, false);
@@ -724,7 +724,7 @@ ssaAddr ssa_build_addr_from_entity(ssaProc *p, Entity *e, AstNode *expr) {
 	ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
 	ssaValue **found = map_ssa_value_get(&p->module->values, hash_pointer(e));
 	if (found) {
 	if (found) {
 		v = *found;
 		v = *found;
-	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
+	} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Using) {
 		// NOTE(bill): Calculate the using variable every time
 		// NOTE(bill): Calculate the using variable every time
 		v = ssa_get_using_variable(p, e);
 		v = ssa_get_using_variable(p, e);
 	}
 	}

+ 11 - 3
src/types.c

@@ -935,13 +935,21 @@ bool are_types_identical(Type *x, Type *y) {
 					    x->Record.custom_align == y->Record.custom_align) {
 					    x->Record.custom_align == y->Record.custom_align) {
 						// TODO(bill); Fix the custom alignment rule
 						// TODO(bill); Fix the custom alignment rule
 						for (isize i = 0; i < x->Record.field_count; i++) {
 						for (isize i = 0; i < x->Record.field_count; i++) {
-							if (!are_types_identical(x->Record.fields[i]->type, y->Record.fields[i]->type)) {
+							Entity *xf = x->Record.fields[i];
+							Entity *yf = y->Record.fields[i];
+							if (!are_types_identical(xf->type, yf->type)) {
 								return false;
 								return false;
 							}
 							}
-							if (str_ne(x->Record.fields[i]->token.string, y->Record.fields[i]->token.string)) {
+							if (str_ne(xf->token.string, yf->token.string)) {
+								return false;
+							}
+							bool xf_is_using = (xf->flags&EntityFlag_Using) != 0;
+							bool yf_is_using = (yf->flags&EntityFlag_Using) != 0;
+							if (xf_is_using ^ yf_is_using) {
 								return false;
 								return false;
 							}
 							}
 						}
 						}
+						// NOTE(bill): zeroth variant is NULL
 						for (isize i = 1; i < x->Record.variant_count; i++) {
 						for (isize i = 1; i < x->Record.variant_count; i++) {
 							if (!are_types_identical(x->Record.variants[i]->type, y->Record.variants[i]->type)) {
 							if (!are_types_identical(x->Record.variants[i]->type, y->Record.variants[i]->type)) {
 								return false;
 								return false;
@@ -1340,7 +1348,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
 				return sel;
 				return sel;
 			}
 			}
 
 
-			if (f->flags & EntityFlag_Anonymous) {
+			if (f->flags & EntityFlag_Using) {
 				isize prev_count = sel.index.count;
 				isize prev_count = sel.index.count;
 				selection_add_index(&sel, i); // HACK(bill): Leaky memory
 				selection_add_index(&sel, i); // HACK(bill): Leaky memory