authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-08 17:29:32-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-08 19:51:35-07:00
log51a8f52e6cdd53321572830efe3ac75cb09b5a09
tree0b263b2bc46765c0c17aa4d06e30e1c7007c6176
parent2fff25fd220632cc6943680d3d6bbb1f21fa141f

stage2: Support `@offsetOf` for tuples and anon structs


3 files changed, 23 insertions(+), 39 deletions(-)

src/Sema.zig+22-32
...@@ -15872,50 +15872,40 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -15872,50 +15872,40 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
15872 const target = sema.mod.getTarget();15872 const target = sema.mod.getTarget();
1587315873
15874 try sema.resolveTypeLayout(block, lhs_src, ty);15874 try sema.resolveTypeLayout(block, lhs_src, ty);
15875 if (ty.tag() != .@"struct") {15875 switch (ty.tag()) {
15876 const msg = msg: {15876 .@"struct", .tuple, .anon_struct => {},
15877 const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)});15877 else => {
15878 errdefer msg.destroy(sema.gpa);15878 const msg = msg: {
15879 try sema.addDeclaredHereNote(msg, ty);15879 const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)});
15880 break :msg msg;15880 errdefer msg.destroy(sema.gpa);
15881 };15881 try sema.addDeclaredHereNote(msg, ty);
15882 return sema.failWithOwnedErrorMsg(block, msg);15882 break :msg msg;
15883 };
15884 return sema.failWithOwnedErrorMsg(block, msg);
15885 },
15883 }15886 }
1588415887
15885 const fields = ty.structFields();15888 const field_index = if (ty.isTuple()) b: {
15886 const index = fields.getIndex(field_name) orelse {15889 if (std.fmt.parseUnsigned(u32, field_name, 10)) |idx| {
15887 const msg = msg: {15890 if (idx < ty.structFieldCount()) break :b idx;
15888 const msg = try sema.errMsg(15891 } else |_| {}
15889 block,15892 return sema.fail(block, rhs_src, "tuple '{}' has no such field '{s}'", .{
15890 rhs_src,15893 ty.fmt(sema.mod), field_name,
15891 "struct '{}' has no field '{s}'",15894 });
15892 .{ ty.fmt(sema.mod), field_name },15895 } else try sema.structFieldIndex(block, ty, field_name, rhs_src);
15893 );
15894 errdefer msg.destroy(sema.gpa);
15895 try sema.addDeclaredHereNote(msg, ty);
15896 break :msg msg;
15897 };
15898 return sema.failWithOwnedErrorMsg(block, msg);
15899 };
1590015896
15901 switch (ty.containerLayout()) {15897 switch (ty.containerLayout()) {
15902 .Packed => {15898 .Packed => {
15903 var bit_sum: u64 = 0;15899 var bit_sum: u64 = 0;
15900 const fields = ty.structFields();
15904 for (fields.values()) |field, i| {15901 for (fields.values()) |field, i| {
15905 if (i == index) {15902 if (i == field_index) {
15906 return bit_sum;15903 return bit_sum;
15907 }15904 }
15908 bit_sum += field.ty.bitSize(target);15905 bit_sum += field.ty.bitSize(target);
15909 } else unreachable;15906 } else unreachable;
15910 },15907 },
15911 else => {15908 else => return ty.structFieldOffset(field_index, target) * 8,
15912 var it = ty.iterateStructOffsets(target);
15913 while (it.next()) |field_offset| {
15914 if (field_offset.field == index) {
15915 return field_offset.offset * 8;
15916 }
15917 } else unreachable;
15918 },
15919 }15909 }
15920}15910}
1592115911
test/behavior/tuple.zig-6
...@@ -221,20 +221,14 @@ test "fieldParentPtr of anon struct" {...@@ -221,20 +221,14 @@ test "fieldParentPtr of anon struct" {
221}221}
222222
223test "offsetOf tuple" {223test "offsetOf tuple" {
224 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
225
226 var x: u32 = 0;224 var x: u32 = 0;
227 const T = @TypeOf(.{ x, x });225 const T = @TypeOf(.{ x, x });
228
229 _ = @offsetOf(T, "1");226 _ = @offsetOf(T, "1");
230}227}
231228
232test "offsetOf anon struct" {229test "offsetOf anon struct" {
233 if (builtin.zig_backend != .stage1) return error.SkipZigTest;
234
235 var x: u32 = 0;230 var x: u32 = 0;
236 const T = @TypeOf(.{ .foo = x, .bar = x });231 const T = @TypeOf(.{ .foo = x, .bar = x });
237
238 _ = @offsetOf(T, "bar");232 _ = @offsetOf(T, "bar");
239}233}
240234
test/cases/compile_errors/offsetOf-bad_field_name.zig+1-1
...@@ -9,5 +9,5 @@ export fn foo() usize {...@@ -9,5 +9,5 @@ export fn foo() usize {
9// backend=stage29// backend=stage2
10// target=native10// target=native
11//11//
12// :5:27: error: struct 'tmp.Foo' has no field 'a'12// :5:27: error: no field named 'a' in struct 'tmp.Foo'
13// :1:13: note: struct declared here13// :1:13: note: struct declared here