Skip to content

Commit 51a8f52

Browse files
committed
stage2: Support @offsetOf for tuples and anon structs
1 parent 2fff25f commit 51a8f52

File tree

3 files changed

+23
-39
lines changed

3 files changed

+23
-39
lines changed

src/Sema.zig

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15872,50 +15872,40 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
1587215872
const target = sema.mod.getTarget();
1587315873

1587415874
try sema.resolveTypeLayout(block, lhs_src, ty);
15875-
if (ty.tag() != .@"struct") {
15876-
const msg = msg: {
15877-
const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)});
15878-
errdefer msg.destroy(sema.gpa);
15879-
try sema.addDeclaredHereNote(msg, ty);
15880-
break :msg msg;
15881-
};
15882-
return sema.failWithOwnedErrorMsg(block, msg);
15875+
switch (ty.tag()) {
15876+
.@"struct", .tuple, .anon_struct => {},
15877+
else => {
15878+
const msg = msg: {
15879+
const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)});
15880+
errdefer msg.destroy(sema.gpa);
15881+
try sema.addDeclaredHereNote(msg, ty);
15882+
break :msg msg;
15883+
};
15884+
return sema.failWithOwnedErrorMsg(block, msg);
15885+
},
1588315886
}
1588415887

15885-
const fields = ty.structFields();
15886-
const index = fields.getIndex(field_name) orelse {
15887-
const msg = msg: {
15888-
const msg = try sema.errMsg(
15889-
block,
15890-
rhs_src,
15891-
"struct '{}' has no field '{s}'",
15892-
.{ ty.fmt(sema.mod), field_name },
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-
};
15888+
const field_index = if (ty.isTuple()) b: {
15889+
if (std.fmt.parseUnsigned(u32, field_name, 10)) |idx| {
15890+
if (idx < ty.structFieldCount()) break :b idx;
15891+
} else |_| {}
15892+
return sema.fail(block, rhs_src, "tuple '{}' has no such field '{s}'", .{
15893+
ty.fmt(sema.mod), field_name,
15894+
});
15895+
} else try sema.structFieldIndex(block, ty, field_name, rhs_src);
1590015896

1590115897
switch (ty.containerLayout()) {
1590215898
.Packed => {
1590315899
var bit_sum: u64 = 0;
15900+
const fields = ty.structFields();
1590415901
for (fields.values()) |field, i| {
15905-
if (i == index) {
15902+
if (i == field_index) {
1590615903
return bit_sum;
1590715904
}
1590815905
bit_sum += field.ty.bitSize(target);
1590915906
} else unreachable;
1591015907
},
15911-
else => {
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-
},
15908+
else => return ty.structFieldOffset(field_index, target) * 8,
1591915909
}
1592015910
}
1592115911

test/behavior/tuple.zig

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,20 +221,14 @@ test "fieldParentPtr of anon struct" {
221221
}
222222

223223
test "offsetOf tuple" {
224-
if (builtin.zig_backend != .stage1) return error.SkipZigTest;
225-
226224
var x: u32 = 0;
227225
const T = @TypeOf(.{ x, x });
228-
229226
_ = @offsetOf(T, "1");
230227
}
231228

232229
test "offsetOf anon struct" {
233-
if (builtin.zig_backend != .stage1) return error.SkipZigTest;
234-
235230
var x: u32 = 0;
236231
const T = @TypeOf(.{ .foo = x, .bar = x });
237-
238232
_ = @offsetOf(T, "bar");
239233
}
240234

test/cases/compile_errors/offsetOf-bad_field_name.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ export fn foo() usize {
99
// backend=stage2
1010
// target=native
1111
//
12-
// :5:27: error: struct 'tmp.Foo' has no field 'a'
12+
// :5:27: error: no field named 'a' in struct 'tmp.Foo'
1313
// :1:13: note: struct declared here

0 commit comments

Comments
 (0)