authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-08 17:30:06-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-07-08 19:52:23-07:00
logc830606bbee72054749d4bf56e9215cac7785afa
tree36427f467bfa85cbf5837d64b8c8f41add6b2d3f
parent51a8f52e6cdd53321572830efe3ac75cb09b5a09

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


2 files changed, 21 insertions(+), 9 deletions(-)

src/Sema.zig+13-7
...@@ -17173,24 +17173,30 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -17173,24 +17173,30 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
17173 }17173 }
17174 try sema.resolveTypeLayout(block, ty_src, struct_ty);17174 try sema.resolveTypeLayout(block, ty_src, struct_ty);
1717517175
17176 const struct_obj = struct_ty.castTag(.@"struct").?.data;17176 const field_index = if (struct_ty.isTuple()) b: {
17177 const field_index = struct_obj.fields.getIndex(field_name) orelse17177 if (std.fmt.parseUnsigned(u32, field_name, 10)) |idx| {
17178 return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);17178 if (idx < struct_ty.structFieldCount()) break :b idx;
17179 } else |_| {}
17180 return sema.fail(block, name_src, "tuple '{}' has no such field '{s}'", .{
17181 struct_ty.fmt(sema.mod), field_name,
17182 });
17183 } else try sema.structFieldIndex(block, struct_ty, field_name, name_src);
1717917184
17180 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);17185 try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
17181 const field = struct_obj.fields.values()[field_index];
17182 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;17186 const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
1718317187
17184 var ptr_ty_data: Type.Payload.Pointer.Data = .{17188 var ptr_ty_data: Type.Payload.Pointer.Data = .{
17185 .pointee_type = field.ty,17189 .pointee_type = struct_ty.structFieldType(field_index),
17186 .mutable = field_ptr_ty_info.mutable,17190 .mutable = field_ptr_ty_info.mutable,
17187 .@"addrspace" = field_ptr_ty_info.@"addrspace",17191 .@"addrspace" = field_ptr_ty_info.@"addrspace",
17188 };17192 };
1718917193
17190 if (struct_obj.layout == .Packed) {17194 if (struct_ty.containerLayout() == .Packed) {
17191 return sema.fail(block, src, "TODO handle packed structs with @fieldParentPtr", .{});17195 return sema.fail(block, src, "TODO handle packed structs with @fieldParentPtr", .{});
17192 } else {17196 } else {
17193 ptr_ty_data.@"align" = field.abi_align;17197 ptr_ty_data.@"align" = if (struct_ty.castTag(.@"struct")) |struct_obj| b: {
17198 break :b struct_obj.data.fields.values()[field_index].abi_align;
17199 } else 0;
17194 }17200 }
1719517201
17196 const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);17202 const actual_field_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
test/behavior/tuple.zig+8-2
...@@ -205,7 +205,10 @@ test "initializing anon struct with explicit type" {...@@ -205,7 +205,10 @@ test "initializing anon struct with explicit type" {
205}205}
206206
207test "fieldParentPtr of tuple" {207test "fieldParentPtr of tuple" {
208 if (builtin.zig_backend != .stage1) return error.SkipZigTest;208 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
209 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
210 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
211 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
209212
210 var x: u32 = 0;213 var x: u32 = 0;
211 const tuple = .{ x, x };214 const tuple = .{ x, x };
...@@ -213,7 +216,10 @@ test "fieldParentPtr of tuple" {...@@ -213,7 +216,10 @@ test "fieldParentPtr of tuple" {
213}216}
214217
215test "fieldParentPtr of anon struct" {218test "fieldParentPtr of anon struct" {
216 if (builtin.zig_backend != .stage1) return error.SkipZigTest;219 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
220 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
221 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
222 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
217223
218 var x: u32 = 0;224 var x: u32 = 0;
219 const anon_st = .{ .foo = x, .bar = x };225 const anon_st = .{ .foo = x, .bar = x };