Browse Source

`#panic`; Minor change to demo.odin; Fix `#assert` bug at file scope

gingerBill 5 years ago
parent
commit
2a6d9e8927
10 changed files with 145 additions and 122 deletions
  1. 1 1
      core/odin/parser/parser.odin
  2. 28 26
      core/runtime/core.odin
  3. 10 10
      examples/demo/demo.odin
  4. 20 2
      src/check_expr.cpp
  5. 30 7
      src/check_type.cpp
  6. 10 3
      src/checker.cpp
  7. 1 0
      src/checker.hpp
  8. 5 9
      src/main.cpp
  9. 4 34
      src/parser.cpp
  10. 36 30
      src/types.cpp

+ 1 - 1
core/odin/parser/parser.odin

@@ -1091,7 +1091,7 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
 			case: error(p, stmt.pos, "#complete can only be applied to a switch statement");
 			}
 			return stmt;
-		case "assert":
+		case "assert", "panic":
 			bd := ast.new(ast.Basic_Directive, tok.pos, end_pos(tag));
 			bd.tok  = tok;
 			bd.name = name;

+ 28 - 26
core/runtime/core.odin

@@ -6,6 +6,7 @@ package runtime
 import "core:os"
 import "core:mem"
 import "core:log"
+import "intrinsics"
 
 // Naming Conventions:
 // In general, Ada_Case for types and snake_case for values
@@ -187,12 +188,13 @@ Typeid_Kind :: enum u8 {
 #assert(len(Typeid_Kind) < 32);
 
 Typeid_Bit_Field :: bit_field #align align_of(uintptr) {
-	index:    8*size_of(align_of(uintptr)) - 8,
+	index:    8*size_of(uintptr) - 8,
 	kind:     5, // Typeid_Kind
 	named:    1,
 	special:  1, // signed, cstring, etc
 	reserved: 1,
 }
+#assert(size_of(Typeid_Bit_Field) == size_of(uintptr));
 
 // NOTE(bill): only the ones that are needed (not all types)
 // This will be set by the compiler
@@ -678,7 +680,7 @@ assert :: proc(condition: bool, message := "", loc := #caller_location) -> bool
 			if p == nil {
 				p = default_assertion_failure_proc;
 			}
-			p("Runtime assertion", message, loc);
+			p("runtime assertion", message, loc);
 		}(message, loc);
 	}
 	return condition;
@@ -690,7 +692,7 @@ panic :: proc(message: string, loc := #caller_location) -> ! {
 	if p == nil {
 		p = default_assertion_failure_proc;
 	}
-	p("Panic", message, loc);
+	p("panic", message, loc);
 }
 
 @builtin
@@ -816,8 +818,7 @@ __get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> Map_Header {
 		value: V,
 	};
 
-	_, is_string := type_info_base(type_info_of(K)).variant.(Type_Info_String);
-	header.is_key_string = is_string;
+	header.is_key_string = intrinsics.type_is_string(K);
 	header.entry_size    = int(size_of(Entry));
 	header.entry_align   = int(align_of(Entry));
 	header.value_offset  = uintptr(offset_of(Entry, value));
@@ -828,33 +829,34 @@ __get_map_header :: proc "contextless" (m: ^$T/map[$K]$V) -> Map_Header {
 __get_map_key :: proc "contextless" (k: $K) -> Map_Key {
 	key := k;
 	map_key: Map_Key;
-	ti := type_info_base_without_enum(type_info_of(K));
-	switch _ in ti.variant {
-	case Type_Info_Integer:
-		switch 8*size_of(key) {
-		case   8: map_key.hash = u64((  ^u8)(&key)^);
-		case  16: map_key.hash = u64(( ^u16)(&key)^);
-		case  32: map_key.hash = u64(( ^u32)(&key)^);
-		case  64: map_key.hash = u64(( ^u64)(&key)^);
-		case: panic("Unhandled integer size");
-		}
-	case Type_Info_Rune:
+
+	T :: intrinsics.type_core_type(K);
+
+	when intrinsics.type_is_integer(T) {
+		sz :: 8*size_of(T);
+		     when sz ==  8 do map_key.hash = u64(( ^u8)(&key)^);
+		else when sz == 16 do map_key.hash = u64((^u16)(&key)^);
+		else when sz == 32 do map_key.hash = u64((^u32)(&key)^);
+		else when sz == 64 do map_key.hash = u64((^u64)(&key)^);
+		else do #assert(false, "Unhandled integer size");
+	} else when intrinsics.type_is_rune(T) {
 		map_key.hash = u64((^rune)(&key)^);
-	case Type_Info_Pointer:
+	} else when intrinsics.type_is_pointer(T) {
 		map_key.hash = u64(uintptr((^rawptr)(&key)^));
-	case Type_Info_Float:
-		switch 8*size_of(key) {
-		case 32: map_key.hash = u64((^u32)(&key)^);
-		case 64: map_key.hash = u64((^u64)(&key)^);
-		case: panic("Unhandled float size");
-		}
-	case Type_Info_String:
+	} else when intrinsics.type_is_float(T) {
+		sz :: 8*size_of(T);
+		     when sz == 32 do map_key.hash = u64((^u32)(&key)^);
+		else when sz == 64 do map_key.hash = u64((^u64)(&key)^);
+		else do #assert(false, "Unhandled float size");
+	} else when intrinsics.type_is_string(T) {
+		#assert(T == string);
 		str := (^string)(&key)^;
 		map_key.hash = default_hash_string(str);
 		map_key.str  = str;
-	case:
-		panic("Unhandled map key type");
+	} else {
+		#assert(false, "Unhandled map key type");
 	}
+
 	return map_key;
 }
 

+ 10 - 10
examples/demo/demo.odin

@@ -28,9 +28,9 @@ when os.OS == "windows" {
         Answers to common questions about Odin.
 */
 
-@(link_name="general_stuff")
-general_stuff :: proc() {
-	fmt.println("# general_stuff");
+@(link_name="extra_general_stuff")
+extra_general_stuff :: proc() {
+	fmt.println("# extra_general_stuff");
 	{ // `do` for inline statements rather than block
 		foo :: proc() do fmt.println("Foo!");
 		if   false do foo();
@@ -209,8 +209,8 @@ union_type :: proc() {
 		}
 	}
 
-	Vector3 :: struct {x, y, z: f32};
-	Quaternion :: struct {x, y, z, w: f32};
+	Vector3 :: distinct [3]f32;
+	Quaternion :: distinct quaternion128;
 
 	// More realistic examples
 	{
@@ -320,17 +320,17 @@ union_type :: proc() {
 
 		/*
 			Entity :: struct {
-				..
+				...
 				derived: union{^Frog, ^Monster},
 			}
 
 			Frog :: struct {
 				using entity: Entity,
-				..
+				...
 			}
 			Monster :: struct {
 				using entity: Entity,
-				..
+				...
 
 			}
 			new_entity :: proc(T: type) -> ^Entity {
@@ -539,7 +539,7 @@ parametric_polymorphism :: proc() {
 		fmt.println(r);
 		r = 123;
 		fmt.println(r);
-		r = Error.Foo0;
+		r = Error.Foo0; // r = .Foo0; is allow too, see implicit selector expressions below
 		fmt.println(r);
 	}
 
@@ -1190,7 +1190,7 @@ where_clauses :: proc() {
 
 main :: proc() {
 	when true {
-		general_stuff();
+		extra_general_stuff();
 		union_type();
 		parametric_polymorphism();
 		threading_example();

+ 20 - 2
src/check_expr.cpp

@@ -3071,7 +3071,6 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ
 	}
 
 	if (selector->kind != Ast_Ident) {
-	// if (selector->kind != Ast_Ident) {
 		error(selector, "Illegal selector kind: '%.*s'", LIT(ast_strings[selector->kind]));
 		operand->mode = Addressing_Invalid;
 		operand->expr = node;
@@ -3544,6 +3543,25 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
 
 			operand->type = t_untyped_bool;
 			operand->mode = Addressing_Constant;
+		} else if (name == "panic") {
+			if (ce->args.count != 1) {
+				error(call, "'#panic' expects 1 argument, got %td", ce->args.count);
+				return false;
+			}
+			if (!is_type_string(operand->type) && operand->mode != Addressing_Constant) {
+				gbString str = expr_to_string(ce->args[0]);
+				error(call, "'%s' is not a constant string", str);
+				gb_string_free(str);
+				return false;
+			}
+			error(call, "Compile time panic: %.*s", LIT(operand->value.value_string));
+			if (c->proc_name != "") {
+				gbString str = type_to_string(c->curr_proc_sig);
+				error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str);
+				gb_string_free(str);
+			}
+			operand->type = t_invalid;
+			operand->mode = Addressing_NoValue;
 		} else if (name == "defined") {
 			if (ce->args.count != 1) {
 				error(call, "'#defined' expects 1 argument, got %td", ce->args.count);
@@ -6349,7 +6367,7 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call) {
 	    ce->proc->kind == Ast_BasicDirective) {
 		ast_node(bd, BasicDirective, ce->proc);
 		String name = bd->name;
-		if (name == "location" || name == "assert" || name == "defined" || name == "load") {
+		if (name == "location" || name == "assert" || name == "panic" || name == "defined" || name == "load") {
 			operand->mode = Addressing_Builtin;
 			operand->builtin_id = BuiltinProc_DIRECTIVE;
 			operand->expr = ce->proc;

+ 30 - 7
src/check_type.cpp

@@ -1847,7 +1847,7 @@ Array<Type *> systemv_distribute_struct_fields(Type *t) {
 	}
 	auto distributed = array_make<Type *>(heap_allocator(), 0, distributed_cap);
 
-
+	i64 sz = type_size_of(bt);
 	switch (bt->kind) {
 	case Type_Basic:
 		switch (bt->Basic.kind){
@@ -1925,9 +1925,9 @@ Array<Type *> systemv_distribute_struct_fields(Type *t) {
 		array_add(&distributed, t_int);
 		break;
 
+	case Type_Union:
 	case Type_DynamicArray:
 	case Type_Map:
-	case Type_Union:
 	case Type_BitField: // TODO(bill): Ignore?
 		// NOTE(bill, 2019-10-10): Odin specific, don't worry about C calling convention yet
 		goto DEFAULT;
@@ -1937,7 +1937,7 @@ Array<Type *> systemv_distribute_struct_fields(Type *t) {
 	case Type_SimdVector: // TODO(bill): Is this correct logic?
 	default:
 	DEFAULT:;
-		if (type_size_of(bt) > 0) {
+		if (sz > 0) {
 			array_add(&distributed, bt);
 		}
 		break;
@@ -1959,13 +1959,22 @@ Type *handle_single_distributed_type_parameter(Array<Type *> const &types, bool
 
 	if (types.count == 1) {
 		if (offset) *offset = 1;
+
+		i64 sz = type_size_of(types[0]);
+
 		if (is_type_float(types[0])) {
 			return types[0];
-		} else if (type_size_of(types[0]) == 8) {
+		}
+		switch (sz) {
+		case 0:
+			GB_PANIC("Zero sized type found!");
+		case 1:
+		case 2:
+		case 4:
+		case 8:
 			return types[0];
-		} else {
-			return t_u64;
 		}
+		return t_u64;
 	} else if (types.count >= 2) {
 	    if (types[0] == t_f32 && types[1] == t_f32) {
 	    	if (offset) *offset = 2;
@@ -2050,7 +2059,7 @@ Type *handle_struct_system_v_amd64_abi_type(Type *t) {
 		Type *final_type = nullptr;
 
 		if (field_types.count == 0) {
-			return t;
+			final_type = t;
 		} else if (field_types.count == 1) {
 			final_type = field_types[0];
 		} else {
@@ -2072,8 +2081,22 @@ Type *handle_struct_system_v_amd64_abi_type(Type *t) {
 				variables[1] = alloc_entity_param(nullptr, empty_token, two_types[1], false, false);
 				final_type = alloc_type_tuple();
 				final_type->Tuple.variables = variables;
+				if (t->kind == Type_Struct) {
+					// NOTE(bill): Make this packed
+					final_type->Tuple.is_packed = t->Struct.is_packed;
+				}
 			}
 		}
+
+
+		GB_ASSERT(final_type != nullptr);
+		i64 ftsz = type_size_of(final_type);
+		i64 otsz = type_size_of(original_type);
+		if (ftsz != otsz) {
+			// TODO(bill): Handle this case which will be caused by #packed most likely
+			GB_PANIC("Incorrectly handled case for handle_struct_system_v_amd64_abi_type, %lld vs %lld", ftsz, otsz);
+		}
+
 		return final_type;
 	}
 }

+ 10 - 3
src/checker.cpp

@@ -3367,8 +3367,9 @@ bool collect_file_decls(CheckerContext *ctx, Array<Ast *> const &decls) {
 			if (es->expr->kind == Ast_CallExpr) {
 				ast_node(ce, CallExpr, es->expr);
 				if (ce->proc->kind == Ast_BasicDirective) {
-					Operand o = {};
-					check_expr(ctx, &o, es->expr);
+					if (ctx->collect_delayed_decls) {
+						array_add(&ctx->scope->delayed_directives, es->expr);
+					}
 				}
 			}
 		case_end;
@@ -3525,12 +3526,18 @@ void check_import_entities(Checker *c) {
 		for_array(i, pkg->files) {
 			AstFile *f = pkg->files[i];
 			CheckerContext ctx = c->init_ctx;
-
 			add_curr_ast_file(&ctx, f);
+
 			for_array(j, f->scope->delayed_imports) {
 				Ast *decl = f->scope->delayed_imports[j];
 				check_add_import_decl(&ctx, decl);
 			}
+		}
+		for_array(i, pkg->files) {
+			AstFile *f = pkg->files[i];
+			CheckerContext ctx = c->init_ctx;
+			add_curr_ast_file(&ctx, f);
+
 			for_array(j, f->scope->delayed_directives) {
 				Ast *expr = f->scope->delayed_directives[j];
 				Operand o = {};

+ 1 - 0
src/checker.hpp

@@ -222,6 +222,7 @@ struct ForeignContext {
 typedef Array<Entity *> CheckerTypePath;
 typedef Array<Type *>   CheckerPolyPath;
 
+
 // CheckerInfo stores all the symbol information for a type-checked program
 struct CheckerInfo {
 	Map<ExprInfo>         untyped; // Key: Ast * | Expression -> ExprInfo

+ 5 - 9
src/main.cpp

@@ -445,7 +445,7 @@ bool parse_build_flags(Array<String> args) {
 										path = substring(path, 0, string_extension_position(path));
 									}
 								#endif
-								build_context.out_filepath = path;
+								build_context.out_filepath = path_to_full_path(heap_allocator(), path);
 							} else {
 								gb_printf_err("Invalid -out path, got %.*s\n", LIT(path));
 								bad_flags = true;
@@ -624,7 +624,7 @@ bool parse_build_flags(Array<String> args) {
 								break;
 							}
 
-							if (str == "dll") {
+							if (str == "dll" || str == "shared") {
 								build_context.is_dll = true;
 							} else if (str == "exe") {
 								build_context.is_dll = false;
@@ -1112,7 +1112,7 @@ int main(int arg_count, char **arg_ptr) {
 		if (0) {
 #ifdef GB_SYSTEM_UNIX
 		} else if (selected_target_metrics->metrics == &target_essence_amd64) {
-			system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s", 
+			system_exec_command_line_app("linker", "x86_64-essence-gcc \"%.*s.o\" -o \"%.*s\" %.*s",
 					LIT(output_base), LIT(output_base), LIT(build_context.link_flags));
 #endif
 		} else {
@@ -1239,10 +1239,7 @@ int main(int arg_count, char **arg_ptr) {
 			//   This allows you to specify '-f' in a #foreign_system_library,
 			//   without having to implement any new syntax specifically for MacOS.
 			#if defined(GB_SYSTEM_OSX)
-				if (lib.len > 2 && lib[0] == '-' && lib[1] == 'f') {
-					// framework thingie
-					lib_str = gb_string_append_fmt(lib_str, " -framework %.*s ", (int)(lib.len) - 2, lib.text + 2);
-				} else if (string_ends_with(lib, str_lit(".framework"))) {
+				if (string_ends_with(lib, str_lit(".framework"))) {
 					// framework thingie
 					String lib_name = lib;
 					lib_name = remove_extension_from_path(lib_name);
@@ -1251,8 +1248,7 @@ int main(int arg_count, char **arg_ptr) {
 					// static libs, absolute full path relative to the file in which the lib was imported from
 					lib_str = gb_string_append_fmt(lib_str, " %.*s ", LIT(lib));
 				} else if (string_ends_with(lib, str_lit(".dylib"))) {
-					// dynamic lib, relative path to executable
-					// lib_str = gb_string_append_fmt(lib_str, " -l:%s/%.*s ", cwd, LIT(lib));
+					// dynamic lib
 					lib_str = gb_string_append_fmt(lib_str, " -l%.*s ", LIT(lib));
 				} else {
 					// dynamic or static system lib, just link regularly searching system library paths

+ 4 - 34
src/parser.cpp

@@ -3970,34 +3970,6 @@ Ast *parse_stmt(AstFile *f) {
 		return s;
 	}
 
-	// case Token_static: {
-	// 	CommentGroup *docs = f->lead_comment;
-	// 	Token token = expect_token(f, Token_static);
-
-	// 	Ast *decl = nullptr;
-	// 	Array<Ast *> list = parse_lhs_expr_list(f);
-	// 	if (list.count == 0) {
-	// 		syntax_error(token, "Illegal use of 'static' statement");
-	// 		expect_semicolon(f, nullptr);
-	// 		return ast_bad_stmt(f, token, f->curr_token);
-	// 	}
-
-	// 	expect_token_after(f, Token_Colon, "identifier list");
-	// 	decl = parse_value_decl(f, list, docs);
-
-	// 	if (decl != nullptr && decl->kind == Ast_ValueDecl) {
-	// 		if (decl->ValueDecl.is_mutable) {
-	// 			decl->ValueDecl.is_static = true;
-	// 		} else {
-	// 			error(token, "'static' may only be currently used with variable declaration");
-	// 		}
-	// 		return decl;
-	// 	}
-
-	// 	syntax_error(token, "Illegal use of 'static' statement");
-	// 	return ast_bad_stmt(f, token, f->curr_token);
-	// } break;
-
 	case Token_using: {
 		CommentGroup *docs = f->lead_comment;
 		Token token = expect_token(f, Token_using);
@@ -4071,12 +4043,10 @@ Ast *parse_stmt(AstFile *f) {
 		} else if (tag == "assert") {
 			Ast *t = ast_basic_directive(f, hash_token, tag);
 			return ast_expr_stmt(f, parse_call_expr(f, t));
-		} /* else if (name.string == "no_deferred") {
-			s = parse_stmt(f);
-			s->stmt_state_flags |= StmtStateFlag_no_deferred;
-		} */
-
-		if (tag == "include") {
+		} else if (tag == "panic") {
+			Ast *t = ast_basic_directive(f, hash_token, tag);
+			return ast_expr_stmt(f, parse_call_expr(f, t));
+		} else if (tag == "include") {
 			syntax_error(token, "#include is not a valid import declaration kind. Did you mean 'import'?");
 			s = ast_bad_stmt(f, token, f->curr_token);
 		} else {

+ 36 - 30
src/types.cpp

@@ -113,21 +113,22 @@ struct BasicType {
 struct TypeStruct {
 	Array<Entity *> fields;
 	Array<String>   tags;
-	Ast *node;
-	Scope *  scope;
-
-	Array<i64> offsets;
-	bool       are_offsets_set;
-	bool       are_offsets_being_processed;
-	bool       is_packed;
-	bool       is_raw_union;
-	bool       is_polymorphic;
-	bool       is_poly_specialized;
+	Array<i64>      offsets;
+	Ast *           node;
+	Scope *         scope;
+
 	Type *     polymorphic_params; // Type_Tuple
 	Type *     polymorphic_parent;
 
-	i64      custom_align; // NOTE(bill): Only used in structs at the moment
+	i64      custom_align;
 	Entity * names;
+
+	bool are_offsets_set;
+	bool are_offsets_being_processed;
+	bool is_packed;
+	bool is_raw_union;
+	bool is_polymorphic;
+	bool is_poly_specialized;
 };
 
 struct TypeUnion {
@@ -137,12 +138,11 @@ struct TypeUnion {
 	i64           variant_block_size;
 	i64           custom_align;
 	i64           tag_size;
+	Type *        polymorphic_params; // Type_Tuple
+	Type *        polymorphic_parent;
 	bool          no_nil;
-
-	bool       is_polymorphic;
-	bool       is_poly_specialized;
-	Type *     polymorphic_params; // Type_Tuple
-	Type *     polymorphic_parent;
+	bool          is_polymorphic;
+	bool          is_poly_specialized;
 };
 
 #define TYPE_KINDS                                        \
@@ -190,7 +190,9 @@ struct TypeUnion {
 	TYPE_KIND(Tuple, struct {                             \
 		Array<Entity *> variables; /* Entity_Variable */  \
 		Array<i64>      offsets;                          \
+		bool            are_offsets_being_processed;      \
 		bool            are_offsets_set;                  \
+		bool            is_packed;                        \
 	})                                                    \
 	TYPE_KIND(Proc, struct {                              \
 		Ast *node;                                        \
@@ -201,9 +203,8 @@ struct TypeUnion {
 		i32      result_count;                            \
 		Array<Type *> abi_compat_params;                  \
 		Type *   abi_compat_result_type;                  \
-		bool     return_by_pointer;                       \
-		bool     variadic;                                \
 		i32      variadic_index;                          \
+		bool     variadic;                                \
 		bool     require_results;                         \
 		bool     c_vararg;                                \
 		bool     is_polymorphic;                          \
@@ -211,6 +212,7 @@ struct TypeUnion {
 		bool     has_proc_default_values;                 \
 		bool     has_named_results;                       \
 		bool     diverging; /* no return */               \
+		bool     return_by_pointer;                       \
 		u64      tags;                                    \
 		isize    specialization_count;                    \
 		ProcCallingConvention calling_convention;         \
@@ -1782,7 +1784,8 @@ bool are_types_identical(Type *x, Type *y) {
 
 	case Type_Tuple:
 		if (y->kind == Type_Tuple) {
-			if (x->Tuple.variables.count == y->Tuple.variables.count) {
+			if (x->Tuple.variables.count == y->Tuple.variables.count &&
+			    x->Tuple.is_packed == y->Tuple.is_packed) {
 				for_array(i, x->Tuple.variables) {
 					Entity *xe = x->Tuple.variables[i];
 					Entity *ye = y->Tuple.variables[i];
@@ -2231,19 +2234,22 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
 		if (type->Array.count <= 4) {
 			// HACK(bill): Memory leak
 			switch (type->Array.count) {
-			#define _ARRAY_FIELD_CASE(_length, _name) \
-			case (_length): \
-				if (field_name == _name) { \
+			#define _ARRAY_FIELD_CASE_IF(_length, _name) \
+				if (field_name == (_name)) { \
 					selection_add_index(&sel, (_length)-1); \
 					sel.entity = alloc_entity_array_elem(nullptr, make_token_ident(str_lit(_name)), type->Array.elem, (_length)-1); \
 					return sel; \
-				} \
+				}
+			#define _ARRAY_FIELD_CASE(_length, _name0, _name1) \
+			case (_length): \
+				_ARRAY_FIELD_CASE_IF(_length, _name0); \
+				_ARRAY_FIELD_CASE_IF(_length, _name1); \
 				/*fallthrough*/
 
-			_ARRAY_FIELD_CASE(4, "w");
-			_ARRAY_FIELD_CASE(3, "z");
-			_ARRAY_FIELD_CASE(2, "y");
-			_ARRAY_FIELD_CASE(1, "x");
+			_ARRAY_FIELD_CASE(4, "w", "a");
+			_ARRAY_FIELD_CASE(3, "z", "b");
+			_ARRAY_FIELD_CASE(2, "y", "g");
+			_ARRAY_FIELD_CASE(1, "x", "r");
 			default: break;
 
 			#undef _ARRAY_FIELD_CASE
@@ -2590,9 +2596,9 @@ bool type_set_offsets(Type *t) {
 		}
 	} else if (is_type_tuple(t)) {
 		if (!t->Tuple.are_offsets_set) {
-			t->Struct.are_offsets_being_processed = true;
-			t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, false, false);
-			t->Struct.are_offsets_being_processed = false;
+			t->Tuple.are_offsets_being_processed = true;
+			t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, t->Tuple.is_packed, false);
+			t->Tuple.are_offsets_being_processed = false;
 			t->Tuple.are_offsets_set = true;
 			return true;
 		}