Browse Source

Swap memory layout of `any`

Ginger Bill 8 years ago
parent
commit
822bb51b55
7 changed files with 70 additions and 58 deletions
  1. 2 2
      core/_preload.odin
  2. 12 12
      core/fmt.odin
  3. 19 11
      src/check_expr.c
  4. 18 20
      src/ir.c
  5. 2 2
      src/ir_print.c
  6. 4 0
      src/parser.c
  7. 13 11
      src/types.c

+ 2 - 2
core/_preload.odin

@@ -29,6 +29,7 @@ Type_Info_Record :: struct #ordered {
 	types:        []^Type_Info,
 	types:        []^Type_Info,
 	names:        []string,
 	names:        []string,
 	offsets:      []int,  // offsets may not be used in tuples
 	offsets:      []int,  // offsets may not be used in tuples
+	usings:       []bool, // usings may not be used in tuples
 	packed:       bool,
 	packed:       bool,
 	ordered:      bool,
 	ordered:      bool,
 	custom_align: bool,
 	custom_align: bool,
@@ -147,6 +148,7 @@ Allocator :: struct #ordered {
 	data:      rawptr,
 	data:      rawptr,
 }
 }
 
 
+
 Context :: struct #ordered {
 Context :: struct #ordered {
 	thread_id: int,
 	thread_id: int,
 
 
@@ -277,8 +279,6 @@ default_allocator :: proc() -> Allocator {
 
 
 
 
 
 
-
-
 __string_eq :: proc(a, b: string) -> bool {
 __string_eq :: proc(a, b: string) -> bool {
 	if len(a) != len(b) {
 	if len(a) != len(b) {
 		return false;
 		return false;

+ 12 - 12
core/fmt.odin

@@ -669,12 +669,12 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 	case Enum:
 	case Enum:
 		match verb {
 		match verb {
 		case 'd', 'f':
 		case 'd', 'f':
-			fmt_arg(fi, any{type_info_base(e.base), v.data}, verb);
+			fmt_arg(fi, any{v.data, type_info_base(e.base)}, verb);
 		case 's', 'v':
 		case 's', 'v':
 			i: i64;
 			i: i64;
 			f: f64;
 			f: f64;
 			ok := false;
 			ok := false;
-			a := any{type_info_base(e.base), v.data};
+			a := any{v.data, type_info_base(e.base)};
 			match v in a {
 			match v in a {
 			case i8:   i = cast(i64)v;
 			case i8:   i = cast(i64)v;
 			case i16:  i = cast(i64)v;
 			case i16:  i = cast(i64)v;
@@ -746,12 +746,12 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				write_string(fi.buf, b.names[i]);
 				write_string(fi.buf, b.names[i]);
 				write_string(fi.buf, " = ");
 				write_string(fi.buf, " = ");
 				data := cast(^byte)v.data + b.offsets[i];
 				data := cast(^byte)v.data + b.offsets[i];
-				fmt_arg(fi, any{b.types[i], cast(rawptr)data}, 'v');
+				fmt_arg(fi, any{cast(rawptr)data, b.types[i]}, 'v');
 			}
 			}
 			write_byte(fi.buf, '}');
 			write_byte(fi.buf, '}');
 
 
 		default:
 		default:
-			fmt_value(fi, any{info.base, v.data}, verb);
+			fmt_value(fi, any{v.data, info.base}, verb);
 		}
 		}
 
 
 	case Boolean:    fmt_arg(fi, v, verb);
 	case Boolean:    fmt_arg(fi, v, verb);
@@ -781,7 +781,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				write_string(fi.buf, ", ");
 				write_string(fi.buf, ", ");
 			}
 			}
 			data := cast(^byte)v.data + i*info.elem_size;
 			data := cast(^byte)v.data + i*info.elem_size;
-			fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v');
+			fmt_arg(fi, any{cast(rawptr)data, info.elem}, 'v');
 		}
 		}
 
 
 	case Dynamic_Array:
 	case Dynamic_Array:
@@ -798,7 +798,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				write_string(fi.buf, ", ");
 				write_string(fi.buf, ", ");
 			}
 			}
 			data := cast(^byte)array.data + i*info.elem_size;
 			data := cast(^byte)array.data + i*info.elem_size;
-			fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v');
+			fmt_arg(fi, any{cast(rawptr)data, info.elem}, 'v');
 		}
 		}
 
 
 	case Map:
 	case Map:
@@ -826,13 +826,13 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				write_string(fi.buf, header.key.str);
 				write_string(fi.buf, header.key.str);
 			} else {
 			} else {
 				fi := Fmt_Info{buf = fi.buf};
 				fi := Fmt_Info{buf = fi.buf};
-				fmt_arg(^fi, any{info.key, cast(rawptr)^header.key.hash}, 'v');
+				fmt_arg(^fi, any{cast(rawptr)^header.key.hash, info.key}, 'v');
 			}
 			}
 
 
 			write_string(fi.buf, "=");
 			write_string(fi.buf, "=");
 
 
 			value := data + entry_type.offsets[2];
 			value := data + entry_type.offsets[2];
-			fmt_arg(fi, any{info.value, cast(rawptr)value}, 'v');
+			fmt_arg(fi, any{cast(rawptr)value, info.value}, 'v');
 		}
 		}
 
 
 	case Slice:
 	case Slice:
@@ -849,7 +849,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 				write_string(fi.buf, ", ");
 				write_string(fi.buf, ", ");
 			}
 			}
 			data := ^slice[0] + i*info.elem_size;
 			data := ^slice[0] + i*info.elem_size;
-			fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v');
+			fmt_arg(fi, any{cast(rawptr)data, info.elem}, 'v');
 		}
 		}
 
 
 	case Vector:
 	case Vector:
@@ -862,7 +862,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			}
 			}
 
 
 			data := cast(^byte)v.data + i*info.elem_size;
 			data := cast(^byte)v.data + i*info.elem_size;
-			fmt_value(fi, any{info.elem, cast(rawptr)data}, 'v');
+			fmt_value(fi, any{cast(rawptr)data, info.elem}, 'v');
 		}
 		}
 
 
 	case Struct:
 	case Struct:
@@ -876,7 +876,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			write_string(fi.buf, info.names[i]);
 			write_string(fi.buf, info.names[i]);
 			write_string(fi.buf, " = ");
 			write_string(fi.buf, " = ");
 			data := cast(^byte)v.data + info.offsets[i];
 			data := cast(^byte)v.data + info.offsets[i];
-			fmt_value(fi, any{info.types[i], cast(rawptr)data}, 'v');
+			fmt_value(fi, any{cast(rawptr)data, info.types[i]}, 'v');
 		}
 		}
 
 
 	case Union:
 	case Union:
@@ -892,7 +892,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
 			write_string(fi.buf, cf.names[i]);
 			write_string(fi.buf, cf.names[i]);
 			write_string(fi.buf, " = ");
 			write_string(fi.buf, " = ");
 			data := cast(^byte)v.data + cf.offsets[i];
 			data := cast(^byte)v.data + cf.offsets[i];
-			fmt_value(fi, any{cf.types[i], cast(rawptr)data}, 'v');
+			fmt_value(fi, any{cast(rawptr)data, cf.types[i]}, 'v');
 		}
 		}
 
 
 	case Raw_Union:
 	case Raw_Union:

+ 19 - 11
src/check_expr.c

@@ -86,10 +86,10 @@ bool check_is_assignable_to_using_subtype(Type *dst, Type *src) {
 	src_is_ptr = src != prev_src;
 	src_is_ptr = src != prev_src;
 	src = base_type(src);
 	src = base_type(src);
 
 
-	if (is_type_struct(src)) {
+	if (is_type_struct(src) || is_type_union(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_Using)) {
+			if (f->kind == Entity_Variable && (f->flags & EntityFlag_Using) != 0) {
 				if (are_types_identical(dst, f->type)) {
 				if (are_types_identical(dst, f->type)) {
 					return true;
 					return true;
 				}
 				}
@@ -203,6 +203,7 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) {
 		}
 		}
 	}
 	}
 
 
+
 	if (is_type_any(dst)) {
 	if (is_type_any(dst)) {
 		// NOTE(bill): Anything can cast to `Any`
 		// NOTE(bill): Anything can cast to `Any`
 		add_type_info_type(c, s);
 		add_type_info_type(c, s);
@@ -442,8 +443,9 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 // TODO(bill): Inline sorting procedure?
 // TODO(bill): Inline sorting procedure?
 gb_global gbAllocator   __checker_allocator = {0};
 gb_global gbAllocator   __checker_allocator = {0};
 
 
-GB_COMPARE_PROC(cmp_struct_entity_size) {
+GB_COMPARE_PROC(cmp_reorder_struct_fields) {
 	// Rule:
 	// Rule:
+	// `using` over non-`using`
 	// Biggest to smallest alignment
 	// Biggest to smallest alignment
 	// if same alignment: biggest to smallest size
 	// if same alignment: biggest to smallest size
 	// if same size: order by source order
 	// if same size: order by source order
@@ -453,19 +455,25 @@ GB_COMPARE_PROC(cmp_struct_entity_size) {
 	GB_ASSERT(y != NULL);
 	GB_ASSERT(y != NULL);
 	GB_ASSERT(x->kind == Entity_Variable);
 	GB_ASSERT(x->kind == Entity_Variable);
 	GB_ASSERT(y->kind == Entity_Variable);
 	GB_ASSERT(y->kind == Entity_Variable);
+	bool xu = (x->flags & EntityFlag_Using) != 0;
+	bool yu = (y->flags & EntityFlag_Using) != 0;
 	i64 xa = type_align_of(__checker_allocator, x->type);
 	i64 xa = type_align_of(__checker_allocator, x->type);
 	i64 ya = type_align_of(__checker_allocator, y->type);
 	i64 ya = type_align_of(__checker_allocator, y->type);
 	i64 xs = type_size_of(__checker_allocator, x->type);
 	i64 xs = type_size_of(__checker_allocator, x->type);
 	i64 ys = type_size_of(__checker_allocator, y->type);
 	i64 ys = type_size_of(__checker_allocator, y->type);
 
 
-	if (xa == ya) {
-		if (xs == ys) {
-			i32 diff = x->Variable.field_index - y->Variable.field_index;
-			return diff < 0 ? -1 : diff > 0;
-		}
+	if (xu != yu) {
+		return xu ? -1 : +1;
+	}
+
+	if (xa != ya) {
+		return xa > ya ? -1 : xa < ya;
+	}
+	if (xs != ys) {
 		return xs > ys ? -1 : xs < ys;
 		return xs > ys ? -1 : xs < ys;
 	}
 	}
-	return xa > ya ? -1 : xa < ya;
+	i32 diff = x->Variable.field_index - y->Variable.field_index;
+	return diff < 0 ? -1 : diff > 0;
 }
 }
 
 
 Entity *make_names_field_for_record(Checker *c, Scope *scope) {
 Entity *make_names_field_for_record(Checker *c, Scope *scope) {
@@ -513,7 +521,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node) {
 		// TODO(bill): Probably make an inline sorting procedure rather than use global variables
 		// TODO(bill): Probably make an inline sorting procedure rather than use global variables
 		__checker_allocator = c->allocator;
 		__checker_allocator = c->allocator;
 		// NOTE(bill): compound literal order must match source not layout
 		// NOTE(bill): compound literal order must match source not layout
-		gb_sort_array(reordered_fields, field_count, cmp_struct_entity_size);
+		gb_sort_array(reordered_fields, field_count, cmp_reorder_struct_fields);
 
 
 		for (isize i = 0; i < field_count; i++) {
 		for (isize i = 0; i < field_count; i++) {
 			reordered_fields[i]->Variable.field_index = i;
 			reordered_fields[i]->Variable.field_index = i;
@@ -5312,7 +5320,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t
 				break; // NOTE(bill): No need to init
 				break; // NOTE(bill): No need to init
 			}
 			}
 			{ // Checker values
 			{ // Checker values
-				Type *field_types[2] = {t_type_info_ptr, t_rawptr};
+				Type *field_types[2] = {t_rawptr, t_type_info_ptr};
 				isize field_count = 2;
 				isize field_count = 2;
 				if (cl->elems.e[0]->kind == AstNode_FieldValue) {
 				if (cl->elems.e[0]->kind == AstNode_FieldValue) {
 					bool fields_visited[2] = {0};
 					bool fields_visited[2] = {0};

+ 18 - 20
src/ir.c

@@ -2080,15 +2080,15 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
 irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue *x) {
 irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue *x) {
 	Type *t = ir_type(x);
 	Type *t = ir_type(x);
 	if (is_type_any(t)) {
 	if (is_type_any(t)) {
-		irValue *ti = ir_emit_struct_ev(proc, x, 0);
-		irValue *data = ir_emit_struct_ev(proc, x, 1);
+		irValue *data = ir_emit_struct_ev(proc, x, 0);
+		irValue *ti   = ir_emit_struct_ev(proc, x, 1);
 		if (op_kind == Token_CmpEq) {
 		if (op_kind == Token_CmpEq) {
-			irValue *a = ir_emit_comp(proc, Token_CmpEq, ti, v_raw_nil);
-			irValue *b = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
+			irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
+			irValue *b = ir_emit_comp(proc, Token_CmpEq, ti, v_raw_nil);
 			return ir_emit_arith(proc, Token_Or, a, b, t_bool);
 			return ir_emit_arith(proc, Token_Or, a, b, t_bool);
 		} else if (op_kind == Token_NotEq) {
 		} else if (op_kind == Token_NotEq) {
-			irValue *a = ir_emit_comp(proc, Token_NotEq, ti, v_raw_nil);
-			irValue *b = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
+			irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
+			irValue *b = ir_emit_comp(proc, Token_NotEq, ti, v_raw_nil);
 			return ir_emit_arith(proc, Token_And, a, b, t_bool);
 			return ir_emit_arith(proc, Token_And, a, b, t_bool);
 		}
 		}
 	} else if (is_type_slice(t)) {
 	} else if (is_type_slice(t)) {
@@ -2249,8 +2249,8 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
 		}
 		}
 	} else if (is_type_any(t)) {
 	} else if (is_type_any(t)) {
 		switch (index) {
 		switch (index) {
-		case 0: result_type = make_type_pointer(a, t_type_info_ptr); break;
-		case 1: result_type = make_type_pointer(a, t_rawptr);        break;
+		case 0: result_type = make_type_pointer(a, t_rawptr);        break;
+		case 1: result_type = make_type_pointer(a, t_type_info_ptr); break;
 		}
 		}
 	} else if (is_type_dynamic_array(t)) {
 	} else if (is_type_dynamic_array(t)) {
 		switch (index) {
 		switch (index) {
@@ -2322,8 +2322,8 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
 		}
 		}
 	} else if (is_type_any(t)) {
 	} else if (is_type_any(t)) {
 		switch (index) {
 		switch (index) {
-		case 0: result_type = t_type_info_ptr; break;
-		case 1: result_type = t_rawptr;        break;
+		case 0: result_type = t_rawptr;        break;
+		case 1: result_type = t_type_info_ptr; break;
 		}
 		}
 	} else if (is_type_dynamic_array(t)) {
 	} else if (is_type_dynamic_array(t)) {
 		switch (index) {
 		switch (index) {
@@ -2375,9 +2375,9 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
 			switch (type->Basic.kind) {
 			switch (type->Basic.kind) {
 			case Basic_any: {
 			case Basic_any: {
 				if (index == 0) {
 				if (index == 0) {
-					type = t_type_info_ptr;
-				} else if (index == 1) {
 					type = t_rawptr;
 					type = t_rawptr;
+				} else if (index == 1) {
+					type = t_type_info_ptr;
 				}
 				}
 				e = ir_emit_struct_ep(proc, e, index);
 				e = ir_emit_struct_ep(proc, e, index);
 			} break;
 			} break;
@@ -2881,10 +2881,8 @@ irValue *ir_emit_conv(irProcedure *proc, irValue *value, Type *t) {
 
 
 		irValue *ti = ir_type_info(proc, st);
 		irValue *ti = ir_type_info(proc, st);
 
 
-		irValue *gep0 = ir_emit_struct_ep(proc, result, 0);
-		irValue *gep1 = ir_emit_struct_ep(proc, result, 1);
-		ir_emit_store(proc, gep0, ti);
-		ir_emit_store(proc, gep1, data);
+		ir_emit_store(proc, ir_emit_struct_ep(proc, result, 0), data);
+		ir_emit_store(proc, ir_emit_struct_ep(proc, result, 1), ti);
 
 
 		return ir_emit_load(proc, result);
 		return ir_emit_load(proc, result);
 	}
 	}
@@ -5217,12 +5215,12 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) {
 			if (cl->elems.count > 0) {
 			if (cl->elems.count > 0) {
 				ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr)));
 				ir_emit_store(proc, v, ir_add_module_constant(proc->module, type, exact_value_compound(expr)));
 				String field_names[2] = {
 				String field_names[2] = {
-					str_lit("type_info"),
 					str_lit("data"),
 					str_lit("data"),
+					str_lit("type_info"),
 				};
 				};
 				Type *field_types[2] = {
 				Type *field_types[2] = {
-					t_type_info_ptr,
 					t_rawptr,
 					t_rawptr,
+					t_type_info_ptr,
 				};
 				};
 
 
 				for_array(field_index, cl->elems) {
 				for_array(field_index, cl->elems) {
@@ -6322,7 +6320,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 					GB_ASSERT(index != NULL);
 					GB_ASSERT(index != NULL);
 					cond = ir_emit_comp(proc, Token_CmpEq, tag_index, index);
 					cond = ir_emit_comp(proc, Token_CmpEq, tag_index, index);
 				} else if (match_type_kind == MatchType_Any) {
 				} else if (match_type_kind == MatchType_Any) {
-					irValue *any_ti  = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 0));
+					irValue *any_ti  = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 1));
 					irValue *case_ti = ir_type_info(proc, case_type);
 					irValue *case_ti = ir_type_info(proc, case_type);
 					cond = ir_emit_comp(proc, Token_CmpEq, any_ti, case_ti);
 					cond = ir_emit_comp(proc, Token_CmpEq, any_ti, case_ti);
 				}
 				}
@@ -6356,7 +6354,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) {
 				if (match_type_kind == MatchType_Union) {
 				if (match_type_kind == MatchType_Union) {
 					data = union_data;
 					data = union_data;
 				} else if (match_type_kind == MatchType_Any) {
 				} else if (match_type_kind == MatchType_Any) {
-					irValue *any_data = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 1));
+					irValue *any_data = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 0));
 					data = any_data;
 					data = any_data;
 				}
 				}
 				value = ir_emit_conv(proc, data, ct);
 				value = ir_emit_conv(proc, data, ct);

+ 2 - 2
src/ir_print.c

@@ -1596,9 +1596,9 @@ void print_llvm_ir(irGen *ir) {
 
 
 	ir_print_encoded_local(f, str_lit("..any"));
 	ir_print_encoded_local(f, str_lit("..any"));
 	ir_fprintf(f, " = type {");
 	ir_fprintf(f, " = type {");
-	ir_print_type(f, m, t_type_info_ptr);
-	ir_fprintf(f, ", ");
 	ir_print_type(f, m, t_rawptr);
 	ir_print_type(f, m, t_rawptr);
+	ir_fprintf(f, ", ");
+	ir_print_type(f, m, t_type_info_ptr);
 	ir_fprintf(f, "} ; Basic_any\n");
 	ir_fprintf(f, "} ; Basic_any\n");
 
 
 	ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");
 	ir_fprintf(f, "declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone \n");

+ 4 - 0
src/parser.c

@@ -3312,6 +3312,7 @@ AstNode *parse_stmt(AstFile *f) {
 		expect_semicolon(f, decl);
 		expect_semicolon(f, decl);
 
 
 		if (decl->kind == AstNode_ValueDecl) {
 		if (decl->kind == AstNode_ValueDecl) {
+			#if 1
 			if (!decl->ValueDecl.is_var) {
 			if (!decl->ValueDecl.is_var) {
 				syntax_error(token, "`using` may not be applied to constant declarations");
 				syntax_error(token, "`using` may not be applied to constant declarations");
 				return decl;
 				return decl;
@@ -3321,6 +3322,9 @@ AstNode *parse_stmt(AstFile *f) {
 			} else {
 			} else {
 				decl->ValueDecl.flags |= VarDeclFlag_using;
 				decl->ValueDecl.flags |= VarDeclFlag_using;
 			}
 			}
+			#else
+				decl->ValueDecl.flags |= VarDeclFlag_using;
+			#endif
 			return decl;
 			return decl;
 		}
 		}
 
 

+ 13 - 11
src/types.c

@@ -1165,8 +1165,6 @@ ProcTypeOverloadKind are_proc_types_overload_safe(Type *x, Type *y) {
 
 
 
 
 
 
-gb_global Entity *entity__any_type_info  = NULL;
-gb_global Entity *entity__any_data       = NULL;
 
 
 Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel);
 Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel);
 
 
@@ -1219,6 +1217,10 @@ Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) {
 	return empty_selection;
 	return empty_selection;
 }
 }
 
 
+
+gb_global Entity *entity__any_data       = NULL;
+gb_global Entity *entity__any_type_info  = NULL;
+
 Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel) {
 Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel) {
 	GB_ASSERT(type_ != NULL);
 	GB_ASSERT(type_ != NULL);
 
 
@@ -1238,22 +1240,22 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
 		#if 1
 		#if 1
 			// IMPORTANT TODO(bill): Should these members be available to should I only allow them with
 			// IMPORTANT TODO(bill): Should these members be available to should I only allow them with
 			// `Raw_Any` type?
 			// `Raw_Any` type?
-			String type_info_str = str_lit("type_info");
 			String data_str = str_lit("data");
 			String data_str = str_lit("data");
-			if (entity__any_type_info == NULL) {
-				entity__any_type_info = make_entity_field(a, NULL, make_token_ident(type_info_str), t_type_info_ptr, false, 0);
-			}
+			String type_info_str = str_lit("type_info");
 			if (entity__any_data == NULL) {
 			if (entity__any_data == NULL) {
-				entity__any_data = make_entity_field(a, NULL, make_token_ident(data_str), t_rawptr, false, 1);
+				entity__any_data = make_entity_field(a, NULL, make_token_ident(data_str), t_rawptr, false, 0);
+			}
+			if (entity__any_type_info == NULL) {
+				entity__any_type_info = make_entity_field(a, NULL, make_token_ident(type_info_str), t_type_info_ptr, false, 1);
 			}
 			}
 
 
-			if (str_eq(field_name, type_info_str)) {
+			if (str_eq(field_name, data_str)) {
 				selection_add_index(&sel, 0);
 				selection_add_index(&sel, 0);
-				sel.entity = entity__any_type_info;
+				sel.entity = entity__any_data;;
 				return sel;
 				return sel;
-			} else if (str_eq(field_name, data_str)) {
+			} else if (str_eq(field_name, type_info_str)) {
 				selection_add_index(&sel, 1);
 				selection_add_index(&sel, 1);
-				sel.entity = entity__any_data;
+				sel.entity = entity__any_type_info;
 				return sel;
 				return sel;
 			}
 			}
 		#endif
 		#endif