| author | |
| committer | |
| log | 0228887b943dd7e70f7c5cc56e3993769342abf2 |
| tree | 9290c5cdca1974f095efd8ee5dfa9c7ced56689b |
| parent | a4fe438d3940d0beff16c939e991fdff24eb6ba2 |
| parent | 362c87f1aab1db7f0019130115f7cadfef782a56 |
| signature |
Add alignment field to TypeInfo.UnionField and TypeInfo.StructField 7 files changed, 103 insertions(+), 67 deletions(-)
lib/std/builtin.zig+2| ... | ... | @@ -262,6 +262,7 @@ pub const TypeInfo = union(enum) { |
| 262 | 262 | field_type: type, |
| 263 | 263 | default_value: anytype, |
| 264 | 264 | is_comptime: bool, |
| 265 | alignment: comptime_int, | |
| 265 | 266 | }; |
| 266 | 267 | |
| 267 | 268 | /// This data structure is used by the Zig language code generation and |
| ... | ... | @@ -318,6 +319,7 @@ pub const TypeInfo = union(enum) { |
| 318 | 319 | pub const UnionField = struct { |
| 319 | 320 | name: []const u8, |
| 320 | 321 | field_type: type, |
| 322 | alignment: comptime_int, | |
| 321 | 323 | }; |
| 322 | 324 | |
| 323 | 325 | /// This data structure is used by the Zig language code generation and |
lib/std/meta.zig+2| ... | ... | @@ -854,6 +854,7 @@ pub fn ArgsTuple(comptime Function: type) type { |
| 854 | 854 | .field_type = arg.arg_type.?, |
| 855 | 855 | .default_value = @as(?(arg.arg_type.?), null), |
| 856 | 856 | .is_comptime = false, |
| 857 | .alignment = @alignOf(arg.arg_type.?), | |
| 857 | 858 | }; |
| 858 | 859 | } |
| 859 | 860 | |
| ... | ... | @@ -884,6 +885,7 @@ pub fn Tuple(comptime types: []const type) type { |
| 884 | 885 | .field_type = T, |
| 885 | 886 | .default_value = @as(?T, null), |
| 886 | 887 | .is_comptime = false, |
| 888 | .alignment = @alignOf(T), | |
| 887 | 889 | }; |
| 888 | 890 | } |
| 889 | 891 |
lib/std/meta/trailer_flags.zig+1| ... | ... | @@ -47,6 +47,7 @@ pub fn TrailerFlags(comptime Fields: type) type { |
| 47 | 47 | @as(?struct_field.field_type, null), |
| 48 | 48 | ), |
| 49 | 49 | .is_comptime = false, |
| 50 | .alignment = @alignOf(?struct_field.field_type), | |
| 50 | 51 | }; |
| 51 | 52 | } |
| 52 | 53 | break :blk @Type(.{ |
src/stage1/ir.cpp+27-6| ... | ... | @@ -25027,7 +25027,7 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, IrInst *source_instr, |
| 25027 | 25027 | fields[2]->special = ConstValSpecialStatic; |
| 25028 | 25028 | fields[2]->type = ira->codegen->builtin_types.entry_bool; |
| 25029 | 25029 | fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile; |
| 25030 | // alignment: u32 | |
| 25030 | // alignment: comptime_int | |
| 25031 | 25031 | ensure_field_index(result->type, "alignment", 3); |
| 25032 | 25032 | fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int; |
| 25033 | 25033 | if (attrs_type->data.pointer.explicit_alignment != 0) { |
| ... | ... | @@ -25431,11 +25431,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25431 | 25431 | union_field_val->special = ConstValSpecialStatic; |
| 25432 | 25432 | union_field_val->type = type_info_union_field_type; |
| 25433 | 25433 | |
| 25434 | ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 2); | |
| 25434 | ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 3); | |
| 25435 | // field_type: type | |
| 25435 | 25436 | inner_fields[1]->special = ConstValSpecialStatic; |
| 25436 | 25437 | inner_fields[1]->type = ira->codegen->builtin_types.entry_type; |
| 25437 | 25438 | inner_fields[1]->data.x_type = union_field->type_entry; |
| 25438 | 25439 | |
| 25440 | // alignment: comptime_int | |
| 25441 | inner_fields[2]->special = ConstValSpecialStatic; | |
| 25442 | inner_fields[2]->type = ira->codegen->builtin_types.entry_num_lit_int; | |
| 25443 | bigint_init_unsigned(&inner_fields[2]->data.x_bigint, union_field->align); | |
| 25444 | ||
| 25439 | 25445 | ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee; |
| 25440 | 25446 | init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true); |
| 25441 | 25447 | |
| ... | ... | @@ -25502,7 +25508,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25502 | 25508 | struct_field_val->special = ConstValSpecialStatic; |
| 25503 | 25509 | struct_field_val->type = type_info_struct_field_type; |
| 25504 | 25510 | |
| 25505 | ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4); | |
| 25511 | ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 5); | |
| 25506 | 25512 | |
| 25507 | 25513 | inner_fields[1]->special = ConstValSpecialStatic; |
| 25508 | 25514 | inner_fields[1]->type = ira->codegen->builtin_types.entry_type; |
| ... | ... | @@ -25518,10 +25524,16 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy |
| 25518 | 25524 | } |
| 25519 | 25525 | set_optional_payload(inner_fields[2], struct_field->init_val); |
| 25520 | 25526 | |
| 25527 | // is_comptime: bool | |
| 25521 | 25528 | inner_fields[3]->special = ConstValSpecialStatic; |
| 25522 | 25529 | inner_fields[3]->type = ira->codegen->builtin_types.entry_bool; |
| 25523 | 25530 | inner_fields[3]->data.x_bool = struct_field->is_comptime; |
| 25524 | 25531 | |
| 25532 | // alignment: comptime_int | |
| 25533 | inner_fields[4]->special = ConstValSpecialStatic; | |
| 25534 | inner_fields[4]->type = ira->codegen->builtin_types.entry_num_lit_int; | |
| 25535 | bigint_init_unsigned(&inner_fields[4]->data.x_bigint, struct_field->align); | |
| 25536 | ||
| 25525 | 25537 | ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee; |
| 25526 | 25538 | init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true); |
| 25527 | 25539 | |
| ... | ... | @@ -25868,8 +25880,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 25868 | 25880 | buf_sprintf("sentinels are only allowed on slices and unknown-length pointers")); |
| 25869 | 25881 | return ira->codegen->invalid_inst_gen->value->type; |
| 25870 | 25882 | } |
| 25871 | BigInt *bi = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3); | |
| 25872 | if (bi == nullptr) | |
| 25883 | ||
| 25884 | BigInt *alignment = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3); | |
| 25885 | if (alignment == nullptr) | |
| 25873 | 25886 | return ira->codegen->invalid_inst_gen->value->type; |
| 25874 | 25887 | |
| 25875 | 25888 | bool is_const; |
| ... | ... | @@ -25896,7 +25909,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 25896 | 25909 | is_const, |
| 25897 | 25910 | is_volatile, |
| 25898 | 25911 | ptr_len, |
| 25899 | bigint_as_u32(bi), | |
| 25912 | bigint_as_u32(alignment), | |
| 25900 | 25913 | 0, // bit_offset_in_host |
| 25901 | 25914 | 0, // host_int_bytes |
| 25902 | 25915 | is_allowzero, |
| ... | ... | @@ -26133,6 +26146,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26133 | 26146 | } |
| 26134 | 26147 | if ((err = get_const_field_bool(ira, source_instr->source_node, field_value, "is_comptime", 3, &field->is_comptime))) |
| 26135 | 26148 | return ira->codegen->invalid_inst_gen->value->type; |
| 26149 | BigInt *alignment = get_const_field_lit_int(ira, source_instr->source_node, field_value, "alignment", 4); | |
| 26150 | if (alignment == nullptr) | |
| 26151 | return ira->codegen->invalid_inst_gen->value->type; | |
| 26152 | field->align = bigint_as_u32(alignment); | |
| 26136 | 26153 | } |
| 26137 | 26154 | |
| 26138 | 26155 | return entry; |
| ... | ... | @@ -26302,6 +26319,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI |
| 26302 | 26319 | return ira->codegen->invalid_inst_gen->value->type; |
| 26303 | 26320 | field->type_val = type_value; |
| 26304 | 26321 | field->type_entry = type_value->data.x_type; |
| 26322 | BigInt *alignment = get_const_field_lit_int(ira, source_instr->source_node, field_value, "alignment", 2); | |
| 26323 | if (alignment == nullptr) | |
| 26324 | return ira->codegen->invalid_inst_gen->value->type; | |
| 26325 | field->align = bigint_as_u32(alignment); | |
| 26305 | 26326 | } |
| 26306 | 26327 | return entry; |
| 26307 | 26328 | } |
test/compile_errors.zig+51-52| ... | ... | @@ -38,20 +38,39 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 38 | 38 | "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'", |
| 39 | 39 | }); |
| 40 | 40 | |
| 41 | cases.add("slice sentinel mismatch", | |
| 42 | \\export fn entry() void { | |
| 43 | \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 }; | |
| 44 | \\} | |
| 45 | , &[_][]const u8{ | |
| 46 | "tmp.zig:2:62: error: index 3 outside vector of size 3", | |
| 47 | }); | |
| 48 | ||
| 49 | cases.add("slice sentinel mismatch", | |
| 41 | cases.add("@Type for tagged union with extra enum field", | |
| 42 | \\const TypeInfo = @import("builtin").TypeInfo; | |
| 43 | \\const Tag = @Type(.{ | |
| 44 | \\ .Enum = .{ | |
| 45 | \\ .layout = .Auto, | |
| 46 | \\ .tag_type = u2, | |
| 47 | \\ .fields = &[_]TypeInfo.EnumField{ | |
| 48 | \\ .{ .name = "signed", .value = 0 }, | |
| 49 | \\ .{ .name = "unsigned", .value = 1 }, | |
| 50 | \\ .{ .name = "arst", .value = 2 }, | |
| 51 | \\ }, | |
| 52 | \\ .decls = &[_]TypeInfo.Declaration{}, | |
| 53 | \\ .is_exhaustive = true, | |
| 54 | \\ }, | |
| 55 | \\}); | |
| 56 | \\const Tagged = @Type(.{ | |
| 57 | \\ .Union = .{ | |
| 58 | \\ .layout = .Auto, | |
| 59 | \\ .tag_type = Tag, | |
| 60 | \\ .fields = &[_]TypeInfo.UnionField{ | |
| 61 | \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 62 | \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 63 | \\ }, | |
| 64 | \\ .decls = &[_]TypeInfo.Declaration{}, | |
| 65 | \\ }, | |
| 66 | \\}); | |
| 50 | 67 | \\export fn entry() void { |
| 51 | \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 }; | |
| 68 | \\ var tagged = Tagged{ .signed = -1 }; | |
| 69 | \\ tagged = .{ .unsigned = 1 }; | |
| 52 | 70 | \\} |
| 53 | 71 | , &[_][]const u8{ |
| 54 | "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'", | |
| 72 | "tmp.zig:15:23: error: enum field missing: 'arst'", | |
| 73 | "tmp.zig:27:24: note: referenced here", | |
| 55 | 74 | }); |
| 56 | 75 | |
| 57 | 76 | cases.add("@Type for union with opaque field", |
| ... | ... | @@ -61,7 +80,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 61 | 80 | \\ .layout = .Auto, |
| 62 | 81 | \\ .tag_type = null, |
| 63 | 82 | \\ .fields = &[_]TypeInfo.UnionField{ |
| 64 | \\ .{ .name = "foo", .field_type = @Type(.Opaque) }, | |
| 83 | \\ .{ .name = "foo", .field_type = @Type(.Opaque), .alignment = 1 }, | |
| 65 | 84 | \\ }, |
| 66 | 85 | \\ .decls = &[_]TypeInfo.Declaration{}, |
| 67 | 86 | \\ }, |
| ... | ... | @@ -74,6 +93,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 74 | 93 | "tmp.zig:13:17: note: referenced here", |
| 75 | 94 | }); |
| 76 | 95 | |
| 96 | cases.add("slice sentinel mismatch", | |
| 97 | \\export fn entry() void { | |
| 98 | \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 }; | |
| 99 | \\} | |
| 100 | , &[_][]const u8{ | |
| 101 | "tmp.zig:2:62: error: index 3 outside vector of size 3", | |
| 102 | }); | |
| 103 | ||
| 104 | cases.add("slice sentinel mismatch", | |
| 105 | \\export fn entry() void { | |
| 106 | \\ const y: [:1]const u8 = &[_:2]u8{ 1, 2 }; | |
| 107 | \\} | |
| 108 | , &[_][]const u8{ | |
| 109 | "tmp.zig:2:37: error: expected type '[:1]const u8', found '*const [2:2]u8'", | |
| 110 | }); | |
| 111 | ||
| 77 | 112 | cases.add("@Type for union with zero fields", |
| 78 | 113 | \\const TypeInfo = @import("builtin").TypeInfo; |
| 79 | 114 | \\const Untagged = @Type(.{ |
| ... | ... | @@ -130,9 +165,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 130 | 165 | \\ .layout = .Auto, |
| 131 | 166 | \\ .tag_type = Tag, |
| 132 | 167 | \\ .fields = &[_]TypeInfo.UnionField{ |
| 133 | \\ .{ .name = "signed", .field_type = i32 }, | |
| 134 | \\ .{ .name = "unsigned", .field_type = u32 }, | |
| 135 | \\ .{ .name = "arst", .field_type = f32 }, | |
| 168 | \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 169 | \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 170 | \\ .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) }, | |
| 136 | 171 | \\ }, |
| 137 | 172 | \\ .decls = &[_]TypeInfo.Declaration{}, |
| 138 | 173 | \\ }, |
| ... | ... | @@ -147,42 +182,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 147 | 182 | "tmp.zig:27:24: note: referenced here", |
| 148 | 183 | }); |
| 149 | 184 | |
| 150 | cases.add("@Type for tagged union with extra enum field", | |
| 151 | \\const TypeInfo = @import("builtin").TypeInfo; | |
| 152 | \\const Tag = @Type(.{ | |
| 153 | \\ .Enum = .{ | |
| 154 | \\ .layout = .Auto, | |
| 155 | \\ .tag_type = u2, | |
| 156 | \\ .fields = &[_]TypeInfo.EnumField{ | |
| 157 | \\ .{ .name = "signed", .value = 0 }, | |
| 158 | \\ .{ .name = "unsigned", .value = 1 }, | |
| 159 | \\ .{ .name = "arst", .field_type = 2 }, | |
| 160 | \\ }, | |
| 161 | \\ .decls = &[_]TypeInfo.Declaration{}, | |
| 162 | \\ .is_exhaustive = true, | |
| 163 | \\ }, | |
| 164 | \\}); | |
| 165 | \\const Tagged = @Type(.{ | |
| 166 | \\ .Union = .{ | |
| 167 | \\ .layout = .Auto, | |
| 168 | \\ .tag_type = Tag, | |
| 169 | \\ .fields = &[_]TypeInfo.UnionField{ | |
| 170 | \\ .{ .name = "signed", .field_type = i32 }, | |
| 171 | \\ .{ .name = "unsigned", .field_type = u32 }, | |
| 172 | \\ }, | |
| 173 | \\ .decls = &[_]TypeInfo.Declaration{}, | |
| 174 | \\ }, | |
| 175 | \\}); | |
| 176 | \\export fn entry() void { | |
| 177 | \\ var tagged = Tagged{ .signed = -1 }; | |
| 178 | \\ tagged = .{ .unsigned = 1 }; | |
| 179 | \\} | |
| 180 | , &[_][]const u8{ | |
| 181 | "tmp.zig:9:32: error: no member named 'field_type' in struct 'std.builtin.EnumField'", | |
| 182 | "tmp.zig:18:21: note: referenced here", | |
| 183 | "tmp.zig:27:18: note: referenced here", | |
| 184 | }); | |
| 185 | ||
| 186 | 185 | cases.add("@Type with undefined", |
| 187 | 186 | \\comptime { |
| 188 | 187 | \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } }); |
| ... | ... | @@ -7592,7 +7591,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 7592 | 7591 | }); |
| 7593 | 7592 | |
| 7594 | 7593 | cases.add( // fixed bug #2032 |
| 7595 | "compile diagnostic string for top level decl type", | |
| 7594 | "compile diagnostic string for top level decl type", | |
| 7596 | 7595 | \\export fn entry() void { |
| 7597 | 7596 | \\ var foo: u32 = @This(){}; |
| 7598 | 7597 | \\} |
test/stage1/behavior/type.zig+8-8| ... | ... | @@ -320,8 +320,8 @@ test "Type.Union" { |
| 320 | 320 | .layout = .Auto, |
| 321 | 321 | .tag_type = null, |
| 322 | 322 | .fields = &[_]TypeInfo.UnionField{ |
| 323 | .{ .name = "int", .field_type = i32 }, | |
| 324 | .{ .name = "float", .field_type = f32 }, | |
| 323 | .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) }, | |
| 324 | .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) }, | |
| 325 | 325 | }, |
| 326 | 326 | .decls = &[_]TypeInfo.Declaration{}, |
| 327 | 327 | }, |
| ... | ... | @@ -336,8 +336,8 @@ test "Type.Union" { |
| 336 | 336 | .layout = .Packed, |
| 337 | 337 | .tag_type = null, |
| 338 | 338 | .fields = &[_]TypeInfo.UnionField{ |
| 339 | .{ .name = "signed", .field_type = i32 }, | |
| 340 | .{ .name = "unsigned", .field_type = u32 }, | |
| 339 | .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 340 | .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 341 | 341 | }, |
| 342 | 342 | .decls = &[_]TypeInfo.Declaration{}, |
| 343 | 343 | }, |
| ... | ... | @@ -363,8 +363,8 @@ test "Type.Union" { |
| 363 | 363 | .layout = .Auto, |
| 364 | 364 | .tag_type = Tag, |
| 365 | 365 | .fields = &[_]TypeInfo.UnionField{ |
| 366 | .{ .name = "signed", .field_type = i32 }, | |
| 367 | .{ .name = "unsigned", .field_type = u32 }, | |
| 366 | .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, | |
| 367 | .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 368 | 368 | }, |
| 369 | 369 | .decls = &[_]TypeInfo.Declaration{}, |
| 370 | 370 | }, |
| ... | ... | @@ -392,7 +392,7 @@ test "Type.Union from Type.Enum" { |
| 392 | 392 | .layout = .Auto, |
| 393 | 393 | .tag_type = Tag, |
| 394 | 394 | .fields = &[_]TypeInfo.UnionField{ |
| 395 | .{ .name = "working_as_expected", .field_type = u32 }, | |
| 395 | .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 396 | 396 | }, |
| 397 | 397 | .decls = &[_]TypeInfo.Declaration{}, |
| 398 | 398 | }, |
| ... | ... | @@ -408,7 +408,7 @@ test "Type.Union from regular enum" { |
| 408 | 408 | .layout = .Auto, |
| 409 | 409 | .tag_type = E, |
| 410 | 410 | .fields = &[_]TypeInfo.UnionField{ |
| 411 | .{ .name = "working_as_expected", .field_type = u32 }, | |
| 411 | .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) }, | |
| 412 | 412 | }, |
| 413 | 413 | .decls = &[_]TypeInfo.Declaration{}, |
| 414 | 414 | }, |
test/stage1/behavior/type_info.zig+12-1| ... | ... | @@ -211,7 +211,9 @@ fn testUnion() void { |
| 211 | 211 | expect(notag_union_info.Union.tag_type == null); |
| 212 | 212 | expect(notag_union_info.Union.layout == .Auto); |
| 213 | 213 | expect(notag_union_info.Union.fields.len == 2); |
| 214 | expect(notag_union_info.Union.fields[0].alignment == @alignOf(void)); | |
| 214 | 215 | expect(notag_union_info.Union.fields[1].field_type == u32); |
| 216 | expect(notag_union_info.Union.fields[1].alignment == @alignOf(u32)); | |
| 215 | 217 | |
| 216 | 218 | const TestExternUnion = extern union { |
| 217 | 219 | foo: *c_void, |
| ... | ... | @@ -229,13 +231,18 @@ test "type info: struct info" { |
| 229 | 231 | } |
| 230 | 232 | |
| 231 | 233 | fn testStruct() void { |
| 234 | const unpacked_struct_info = @typeInfo(TestUnpackedStruct); | |
| 235 | expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32)); | |
| 236 | ||
| 232 | 237 | const struct_info = @typeInfo(TestStruct); |
| 233 | 238 | expect(struct_info == .Struct); |
| 234 | 239 | expect(struct_info.Struct.layout == .Packed); |
| 235 | 240 | expect(struct_info.Struct.fields.len == 4); |
| 241 | expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize)); | |
| 236 | 242 | expect(struct_info.Struct.fields[2].field_type == *TestStruct); |
| 237 | 243 | expect(struct_info.Struct.fields[2].default_value == null); |
| 238 | 244 | expect(struct_info.Struct.fields[3].default_value.? == 4); |
| 245 | expect(struct_info.Struct.fields[3].alignment == 1); | |
| 239 | 246 | expect(struct_info.Struct.decls.len == 2); |
| 240 | 247 | expect(struct_info.Struct.decls[0].is_pub); |
| 241 | 248 | expect(!struct_info.Struct.decls[0].data.Fn.is_extern); |
| ... | ... | @@ -244,8 +251,12 @@ fn testStruct() void { |
| 244 | 251 | expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void); |
| 245 | 252 | } |
| 246 | 253 | |
| 254 | const TestUnpackedStruct = struct { | |
| 255 | fieldA: u32 = 4, | |
| 256 | }; | |
| 257 | ||
| 247 | 258 | const TestStruct = packed struct { |
| 248 | fieldA: usize, | |
| 259 | fieldA: usize align(2 * @alignOf(usize)), | |
| 249 | 260 | fieldB: void, |
| 250 | 261 | fieldC: *Self, |
| 251 | 262 | fieldD: u32 = 4, |