authorgravatar for alex_naskos@hotmail.comAlexandros Naskos <alex_naskos@hotmail.com> 2020-10-02 02:56:18+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-10-02 02:56:18+03:00
log0228887b943dd7e70f7c5cc56e3993769342abf2
tree9290c5cdca1974f095efd8ee5dfa9c7ced56689b
parenta4fe438d3940d0beff16c939e991fdff24eb6ba2
parent362c87f1aab1db7f0019130115f7cadfef782a56
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #6428 from tadeokondrak/alignment-typeinfo-struct-union

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,6 +262,7 @@ pub const TypeInfo = union(enum) {
262 field_type: type,262 field_type: type,
263 default_value: anytype,263 default_value: anytype,
264 is_comptime: bool,264 is_comptime: bool,
265 alignment: comptime_int,
265 };266 };
266267
267 /// This data structure is used by the Zig language code generation and268 /// This data structure is used by the Zig language code generation and
...@@ -318,6 +319,7 @@ pub const TypeInfo = union(enum) {...@@ -318,6 +319,7 @@ pub const TypeInfo = union(enum) {
318 pub const UnionField = struct {319 pub const UnionField = struct {
319 name: []const u8,320 name: []const u8,
320 field_type: type,321 field_type: type,
322 alignment: comptime_int,
321 };323 };
322324
323 /// This data structure is used by the Zig language code generation and325 /// 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,6 +854,7 @@ pub fn ArgsTuple(comptime Function: type) type {
854 .field_type = arg.arg_type.?,854 .field_type = arg.arg_type.?,
855 .default_value = @as(?(arg.arg_type.?), null),855 .default_value = @as(?(arg.arg_type.?), null),
856 .is_comptime = false,856 .is_comptime = false,
857 .alignment = @alignOf(arg.arg_type.?),
857 };858 };
858 }859 }
859860
...@@ -884,6 +885,7 @@ pub fn Tuple(comptime types: []const type) type {...@@ -884,6 +885,7 @@ pub fn Tuple(comptime types: []const type) type {
884 .field_type = T,885 .field_type = T,
885 .default_value = @as(?T, null),886 .default_value = @as(?T, null),
886 .is_comptime = false,887 .is_comptime = false,
888 .alignment = @alignOf(T),
887 };889 };
888 }890 }
889891
lib/std/meta/trailer_flags.zig+1
...@@ -47,6 +47,7 @@ pub fn TrailerFlags(comptime Fields: type) type {...@@ -47,6 +47,7 @@ pub fn TrailerFlags(comptime Fields: type) type {
47 @as(?struct_field.field_type, null),47 @as(?struct_field.field_type, null),
48 ),48 ),
49 .is_comptime = false,49 .is_comptime = false,
50 .alignment = @alignOf(?struct_field.field_type),
50 };51 };
51 }52 }
52 break :blk @Type(.{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,7 +25027,7 @@ static ZigValue *create_ptr_like_type_info(IrAnalyze *ira, IrInst *source_instr,
25027 fields[2]->special = ConstValSpecialStatic;25027 fields[2]->special = ConstValSpecialStatic;
25028 fields[2]->type = ira->codegen->builtin_types.entry_bool;25028 fields[2]->type = ira->codegen->builtin_types.entry_bool;
25029 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile;25029 fields[2]->data.x_bool = attrs_type->data.pointer.is_volatile;
25030 // alignment: u3225030 // alignment: comptime_int
25031 ensure_field_index(result->type, "alignment", 3);25031 ensure_field_index(result->type, "alignment", 3);
25032 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int;25032 fields[3]->type = ira->codegen->builtin_types.entry_num_lit_int;
25033 if (attrs_type->data.pointer.explicit_alignment != 0) {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,11 +25431,17 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25431 union_field_val->special = ConstValSpecialStatic;25431 union_field_val->special = ConstValSpecialStatic;
25432 union_field_val->type = type_info_union_field_type;25432 union_field_val->type = type_info_union_field_type;
2543325433
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 inner_fields[1]->special = ConstValSpecialStatic;25436 inner_fields[1]->special = ConstValSpecialStatic;
25436 inner_fields[1]->type = ira->codegen->builtin_types.entry_type;25437 inner_fields[1]->type = ira->codegen->builtin_types.entry_type;
25437 inner_fields[1]->data.x_type = union_field->type_entry;25438 inner_fields[1]->data.x_type = union_field->type_entry;
2543825439
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 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee;25445 ZigValue *name = create_const_str_lit(ira->codegen, union_field->name)->data.x_ptr.data.ref.pointee;
25440 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);25446 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(union_field->name), true);
2544125447
...@@ -25502,7 +25508,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -25502,7 +25508,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25502 struct_field_val->special = ConstValSpecialStatic;25508 struct_field_val->special = ConstValSpecialStatic;
25503 struct_field_val->type = type_info_struct_field_type;25509 struct_field_val->type = type_info_struct_field_type;
2550425510
25505 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 4);25511 ZigValue **inner_fields = alloc_const_vals_ptrs(ira->codegen, 5);
2550625512
25507 inner_fields[1]->special = ConstValSpecialStatic;25513 inner_fields[1]->special = ConstValSpecialStatic;
25508 inner_fields[1]->type = ira->codegen->builtin_types.entry_type;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,10 +25524,16 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
25518 }25524 }
25519 set_optional_payload(inner_fields[2], struct_field->init_val);25525 set_optional_payload(inner_fields[2], struct_field->init_val);
2552025526
25527 // is_comptime: bool
25521 inner_fields[3]->special = ConstValSpecialStatic;25528 inner_fields[3]->special = ConstValSpecialStatic;
25522 inner_fields[3]->type = ira->codegen->builtin_types.entry_bool;25529 inner_fields[3]->type = ira->codegen->builtin_types.entry_bool;
25523 inner_fields[3]->data.x_bool = struct_field->is_comptime;25530 inner_fields[3]->data.x_bool = struct_field->is_comptime;
2552425531
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 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;25537 ZigValue *name = create_const_str_lit(ira->codegen, struct_field->name)->data.x_ptr.data.ref.pointee;
25526 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);25538 init_const_slice(ira->codegen, inner_fields[0], name, 0, buf_len(struct_field->name), true);
2552725539
...@@ -25868,8 +25880,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -25868,8 +25880,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
25868 buf_sprintf("sentinels are only allowed on slices and unknown-length pointers"));25880 buf_sprintf("sentinels are only allowed on slices and unknown-length pointers"));
25869 return ira->codegen->invalid_inst_gen->value->type;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);25883
25872 if (bi == nullptr)25884 BigInt *alignment = get_const_field_lit_int(ira, source_instr->source_node, payload, "alignment", 3);
25885 if (alignment == nullptr)
25873 return ira->codegen->invalid_inst_gen->value->type;25886 return ira->codegen->invalid_inst_gen->value->type;
2587425887
25875 bool is_const;25888 bool is_const;
...@@ -25896,7 +25909,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -25896,7 +25909,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
25896 is_const,25909 is_const,
25897 is_volatile,25910 is_volatile,
25898 ptr_len,25911 ptr_len,
25899 bigint_as_u32(bi),25912 bigint_as_u32(alignment),
25900 0, // bit_offset_in_host25913 0, // bit_offset_in_host
25901 0, // host_int_bytes25914 0, // host_int_bytes
25902 is_allowzero,25915 is_allowzero,
...@@ -26133,6 +26146,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26133,6 +26146,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26133 }26146 }
26134 if ((err = get_const_field_bool(ira, source_instr->source_node, field_value, "is_comptime", 3, &field->is_comptime)))26147 if ((err = get_const_field_bool(ira, source_instr->source_node, field_value, "is_comptime", 3, &field->is_comptime)))
26135 return ira->codegen->invalid_inst_gen->value->type;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 }
2613726154
26138 return entry;26155 return entry;
...@@ -26302,6 +26319,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI...@@ -26302,6 +26319,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInst *source_instr, ZigTypeI
26302 return ira->codegen->invalid_inst_gen->value->type;26319 return ira->codegen->invalid_inst_gen->value->type;
26303 field->type_val = type_value;26320 field->type_val = type_value;
26304 field->type_entry = type_value->data.x_type;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 return entry;26327 return entry;
26307 }26328 }
test/compile_errors.zig+51-52
...@@ -38,20 +38,39 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -38,20 +38,39 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
38 "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",38 "tmp.zig:2:20: error: TypeInfo.Enum.tag_type must be an integer type, not 'bool'",
39 });39 });
4040
41 cases.add("slice sentinel mismatch",41 cases.add("@Type for tagged union with extra enum field",
42 \\export fn entry() void {42 \\const TypeInfo = @import("builtin").TypeInfo;
43 \\ const x = @import("std").meta.Vector(3, f32){ 25, 75, 5, 0 };43 \\const Tag = @Type(.{
44 \\}44 \\ .Enum = .{
45 , &[_][]const u8{45 \\ .layout = .Auto,
46 "tmp.zig:2:62: error: index 3 outside vector of size 3",46 \\ .tag_type = u2,
47 });47 \\ .fields = &[_]TypeInfo.EnumField{
4848 \\ .{ .name = "signed", .value = 0 },
49 cases.add("slice sentinel mismatch",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 \\export fn entry() void {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 , &[_][]const u8{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 });
5675
57 cases.add("@Type for union with opaque field",76 cases.add("@Type for union with opaque field",
...@@ -61,7 +80,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -61,7 +80,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
61 \\ .layout = .Auto,80 \\ .layout = .Auto,
62 \\ .tag_type = null,81 \\ .tag_type = null,
63 \\ .fields = &[_]TypeInfo.UnionField{82 \\ .fields = &[_]TypeInfo.UnionField{
64 \\ .{ .name = "foo", .field_type = @Type(.Opaque) },83 \\ .{ .name = "foo", .field_type = @Type(.Opaque), .alignment = 1 },
65 \\ },84 \\ },
66 \\ .decls = &[_]TypeInfo.Declaration{},85 \\ .decls = &[_]TypeInfo.Declaration{},
67 \\ },86 \\ },
...@@ -74,6 +93,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -74,6 +93,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
74 "tmp.zig:13:17: note: referenced here",93 "tmp.zig:13:17: note: referenced here",
75 });94 });
7695
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 cases.add("@Type for union with zero fields",112 cases.add("@Type for union with zero fields",
78 \\const TypeInfo = @import("builtin").TypeInfo;113 \\const TypeInfo = @import("builtin").TypeInfo;
79 \\const Untagged = @Type(.{114 \\const Untagged = @Type(.{
...@@ -130,9 +165,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -130,9 +165,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
130 \\ .layout = .Auto,165 \\ .layout = .Auto,
131 \\ .tag_type = Tag,166 \\ .tag_type = Tag,
132 \\ .fields = &[_]TypeInfo.UnionField{167 \\ .fields = &[_]TypeInfo.UnionField{
133 \\ .{ .name = "signed", .field_type = i32 },168 \\ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
134 \\ .{ .name = "unsigned", .field_type = u32 },169 \\ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
135 \\ .{ .name = "arst", .field_type = f32 },170 \\ .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) },
136 \\ },171 \\ },
137 \\ .decls = &[_]TypeInfo.Declaration{},172 \\ .decls = &[_]TypeInfo.Declaration{},
138 \\ },173 \\ },
...@@ -147,42 +182,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -147,42 +182,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
147 "tmp.zig:27:24: note: referenced here",182 "tmp.zig:27:24: note: referenced here",
148 });183 });
149184
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 cases.add("@Type with undefined",185 cases.add("@Type with undefined",
187 \\comptime {186 \\comptime {
188 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });187 \\ _ = @Type(.{ .Array = .{ .len = 0, .child = u8, .sentinel = undefined } });
...@@ -7592,7 +7591,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -7592,7 +7591,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
7592 });7591 });
75937592
7594 cases.add( // fixed bug #20327593 cases.add( // fixed bug #2032
7595 "compile diagnostic string for top level decl type",7594 "compile diagnostic string for top level decl type",
7596 \\export fn entry() void {7595 \\export fn entry() void {
7597 \\ var foo: u32 = @This(){};7596 \\ var foo: u32 = @This(){};
7598 \\}7597 \\}
test/stage1/behavior/type.zig+8-8
...@@ -320,8 +320,8 @@ test "Type.Union" {...@@ -320,8 +320,8 @@ test "Type.Union" {
320 .layout = .Auto,320 .layout = .Auto,
321 .tag_type = null,321 .tag_type = null,
322 .fields = &[_]TypeInfo.UnionField{322 .fields = &[_]TypeInfo.UnionField{
323 .{ .name = "int", .field_type = i32 },323 .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) },
324 .{ .name = "float", .field_type = f32 },324 .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) },
325 },325 },
326 .decls = &[_]TypeInfo.Declaration{},326 .decls = &[_]TypeInfo.Declaration{},
327 },327 },
...@@ -336,8 +336,8 @@ test "Type.Union" {...@@ -336,8 +336,8 @@ test "Type.Union" {
336 .layout = .Packed,336 .layout = .Packed,
337 .tag_type = null,337 .tag_type = null,
338 .fields = &[_]TypeInfo.UnionField{338 .fields = &[_]TypeInfo.UnionField{
339 .{ .name = "signed", .field_type = i32 },339 .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
340 .{ .name = "unsigned", .field_type = u32 },340 .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
341 },341 },
342 .decls = &[_]TypeInfo.Declaration{},342 .decls = &[_]TypeInfo.Declaration{},
343 },343 },
...@@ -363,8 +363,8 @@ test "Type.Union" {...@@ -363,8 +363,8 @@ test "Type.Union" {
363 .layout = .Auto,363 .layout = .Auto,
364 .tag_type = Tag,364 .tag_type = Tag,
365 .fields = &[_]TypeInfo.UnionField{365 .fields = &[_]TypeInfo.UnionField{
366 .{ .name = "signed", .field_type = i32 },366 .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
367 .{ .name = "unsigned", .field_type = u32 },367 .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
368 },368 },
369 .decls = &[_]TypeInfo.Declaration{},369 .decls = &[_]TypeInfo.Declaration{},
370 },370 },
...@@ -392,7 +392,7 @@ test "Type.Union from Type.Enum" {...@@ -392,7 +392,7 @@ test "Type.Union from Type.Enum" {
392 .layout = .Auto,392 .layout = .Auto,
393 .tag_type = Tag,393 .tag_type = Tag,
394 .fields = &[_]TypeInfo.UnionField{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 .decls = &[_]TypeInfo.Declaration{},397 .decls = &[_]TypeInfo.Declaration{},
398 },398 },
...@@ -408,7 +408,7 @@ test "Type.Union from regular enum" {...@@ -408,7 +408,7 @@ test "Type.Union from regular enum" {
408 .layout = .Auto,408 .layout = .Auto,
409 .tag_type = E,409 .tag_type = E,
410 .fields = &[_]TypeInfo.UnionField{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 .decls = &[_]TypeInfo.Declaration{},413 .decls = &[_]TypeInfo.Declaration{},
414 },414 },
test/stage1/behavior/type_info.zig+12-1
...@@ -211,7 +211,9 @@ fn testUnion() void {...@@ -211,7 +211,9 @@ fn testUnion() void {
211 expect(notag_union_info.Union.tag_type == null);211 expect(notag_union_info.Union.tag_type == null);
212 expect(notag_union_info.Union.layout == .Auto);212 expect(notag_union_info.Union.layout == .Auto);
213 expect(notag_union_info.Union.fields.len == 2);213 expect(notag_union_info.Union.fields.len == 2);
214 expect(notag_union_info.Union.fields[0].alignment == @alignOf(void));
214 expect(notag_union_info.Union.fields[1].field_type == u32);215 expect(notag_union_info.Union.fields[1].field_type == u32);
216 expect(notag_union_info.Union.fields[1].alignment == @alignOf(u32));
215217
216 const TestExternUnion = extern union {218 const TestExternUnion = extern union {
217 foo: *c_void,219 foo: *c_void,
...@@ -229,13 +231,18 @@ test "type info: struct info" {...@@ -229,13 +231,18 @@ test "type info: struct info" {
229}231}
230232
231fn testStruct() void {233fn testStruct() void {
234 const unpacked_struct_info = @typeInfo(TestUnpackedStruct);
235 expect(unpacked_struct_info.Struct.fields[0].alignment == @alignOf(u32));
236
232 const struct_info = @typeInfo(TestStruct);237 const struct_info = @typeInfo(TestStruct);
233 expect(struct_info == .Struct);238 expect(struct_info == .Struct);
234 expect(struct_info.Struct.layout == .Packed);239 expect(struct_info.Struct.layout == .Packed);
235 expect(struct_info.Struct.fields.len == 4);240 expect(struct_info.Struct.fields.len == 4);
241 expect(struct_info.Struct.fields[0].alignment == 2 * @alignOf(usize));
236 expect(struct_info.Struct.fields[2].field_type == *TestStruct);242 expect(struct_info.Struct.fields[2].field_type == *TestStruct);
237 expect(struct_info.Struct.fields[2].default_value == null);243 expect(struct_info.Struct.fields[2].default_value == null);
238 expect(struct_info.Struct.fields[3].default_value.? == 4);244 expect(struct_info.Struct.fields[3].default_value.? == 4);
245 expect(struct_info.Struct.fields[3].alignment == 1);
239 expect(struct_info.Struct.decls.len == 2);246 expect(struct_info.Struct.decls.len == 2);
240 expect(struct_info.Struct.decls[0].is_pub);247 expect(struct_info.Struct.decls[0].is_pub);
241 expect(!struct_info.Struct.decls[0].data.Fn.is_extern);248 expect(!struct_info.Struct.decls[0].data.Fn.is_extern);
...@@ -244,8 +251,12 @@ fn testStruct() void {...@@ -244,8 +251,12 @@ fn testStruct() void {
244 expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void);251 expect(struct_info.Struct.decls[0].data.Fn.fn_type == fn (*const TestStruct) void);
245}252}
246253
254const TestUnpackedStruct = struct {
255 fieldA: u32 = 4,
256};
257
247const TestStruct = packed struct {258const TestStruct = packed struct {
248 fieldA: usize,259 fieldA: usize align(2 * @alignOf(usize)),
249 fieldB: void,260 fieldB: void,
250 fieldC: *Self,261 fieldC: *Self,
251 fieldD: u32 = 4,262 fieldD: u32 = 4,