Commit 51a8f52e6c
Changed files (3)
src
test
behavior
cases
compile_errors
src/Sema.zig
@@ -15872,50 +15872,40 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
const target = sema.mod.getTarget();
try sema.resolveTypeLayout(block, lhs_src, ty);
- if (ty.tag() != .@"struct") {
- const msg = msg: {
- const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)});
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ switch (ty.tag()) {
+ .@"struct", .tuple, .anon_struct => {},
+ else => {
+ const msg = msg: {
+ const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(sema.mod)});
+ errdefer msg.destroy(sema.gpa);
+ try sema.addDeclaredHereNote(msg, ty);
+ break :msg msg;
+ };
+ return sema.failWithOwnedErrorMsg(block, msg);
+ },
}
- const fields = ty.structFields();
- const index = fields.getIndex(field_name) orelse {
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- rhs_src,
- "struct '{}' has no field '{s}'",
- .{ ty.fmt(sema.mod), field_name },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
- };
+ const field_index = if (ty.isTuple()) b: {
+ if (std.fmt.parseUnsigned(u32, field_name, 10)) |idx| {
+ if (idx < ty.structFieldCount()) break :b idx;
+ } else |_| {}
+ return sema.fail(block, rhs_src, "tuple '{}' has no such field '{s}'", .{
+ ty.fmt(sema.mod), field_name,
+ });
+ } else try sema.structFieldIndex(block, ty, field_name, rhs_src);
switch (ty.containerLayout()) {
.Packed => {
var bit_sum: u64 = 0;
+ const fields = ty.structFields();
for (fields.values()) |field, i| {
- if (i == index) {
+ if (i == field_index) {
return bit_sum;
}
bit_sum += field.ty.bitSize(target);
} else unreachable;
},
- else => {
- var it = ty.iterateStructOffsets(target);
- while (it.next()) |field_offset| {
- if (field_offset.field == index) {
- return field_offset.offset * 8;
- }
- } else unreachable;
- },
+ else => return ty.structFieldOffset(field_index, target) * 8,
}
}
test/behavior/tuple.zig
@@ -221,20 +221,14 @@ test "fieldParentPtr of anon struct" {
}
test "offsetOf tuple" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest;
-
var x: u32 = 0;
const T = @TypeOf(.{ x, x });
-
_ = @offsetOf(T, "1");
}
test "offsetOf anon struct" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest;
-
var x: u32 = 0;
const T = @TypeOf(.{ .foo = x, .bar = x });
-
_ = @offsetOf(T, "bar");
}
test/cases/compile_errors/offsetOf-bad_field_name.zig
@@ -9,5 +9,5 @@ export fn foo() usize {
// backend=stage2
// target=native
//
-// :5:27: error: struct 'tmp.Foo' has no field 'a'
+// :5:27: error: no field named 'a' in struct 'tmp.Foo'
// :1:13: note: struct declared here