authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-19 11:55:15+01:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-30 20:50:48-04:00
log17673dcd6e3ffeb25fc9dc1cfc72334ab4e71b37
treea75acd8f0b41030563015bdcdc47b374fb3f8dc3
parente409afb79bcadeabd2d5d4cc3cd5dcc54a964e94

AstGen: use RLS to infer the first argument of `@fieldParentPtr`


9 files changed, 128 insertions(+), 85 deletions(-)

lib/std/zig/AstGen.zig+62-33
......@@ -316,8 +316,7 @@ const ResultInfo = struct {
316316 };
317317
318318 /// Find the result type for a cast builtin given the result location.
319 /// If the location does not have a known result type, emits an error on
320 /// the given node.
319 /// If the location does not have a known result type, returns `null`.
321320 fn resultType(rl: Loc, gz: *GenZir, node: Ast.Node.Index) !?Zir.Inst.Ref {
322321 return switch (rl) {
323322 .discard, .none, .ref, .inferred_ptr, .destructure => null,
......@@ -330,6 +329,9 @@ const ResultInfo = struct {
330329 };
331330 }
332331
332 /// Find the result type for a cast builtin given the result location.
333 /// If the location does not have a known result type, emits an error on
334 /// the given node.
333335 fn resultTypeForCast(rl: Loc, gz: *GenZir, node: Ast.Node.Index, builtin_name: []const u8) !Zir.Inst.Ref {
334336 const astgen = gz.astgen;
335337 if (try rl.resultType(gz, node)) |ty| return ty;
......@@ -2786,7 +2788,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
27862788 .atomic_load,
27872789 .atomic_rmw,
27882790 .mul_add,
2789 .field_parent_ptr,
27902791 .max,
27912792 .min,
27922793 .c_import,
......@@ -8853,6 +8854,7 @@ fn ptrCast(
88538854 const node_datas = tree.nodes.items(.data);
88548855 const node_tags = tree.nodes.items(.tag);
88558856
8857 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
88568858 var flags: Zir.Inst.FullPtrCastFlags = .{};
88578859
88588860 // Note that all pointer cast builtins have one parameter, so we only need
......@@ -8870,36 +8872,62 @@ fn ptrCast(
88708872 }
88718873
88728874 if (node_datas[node].lhs == 0) break; // 0 args
8873 if (node_datas[node].rhs != 0) break; // 2 args
88748875
88758876 const builtin_token = main_tokens[node];
88768877 const builtin_name = tree.tokenSlice(builtin_token);
88778878 const info = BuiltinFn.list.get(builtin_name) orelse break;
8878 if (info.param_count != 1) break;
8879 if (node_datas[node].rhs == 0) {
8880 // 1 arg
8881 if (info.param_count != 1) break;
8882
8883 switch (info.tag) {
8884 else => break,
8885 inline .ptr_cast,
8886 .align_cast,
8887 .addrspace_cast,
8888 .const_cast,
8889 .volatile_cast,
8890 => |tag| {
8891 if (@field(flags, @tagName(tag))) {
8892 return astgen.failNode(node, "redundant {s}", .{builtin_name});
8893 }
8894 @field(flags, @tagName(tag)) = true;
8895 },
8896 }
88798897
8880 switch (info.tag) {
8881 else => break,
8882 inline .ptr_cast,
8883 .align_cast,
8884 .addrspace_cast,
8885 .const_cast,
8886 .volatile_cast,
8887 => |tag| {
8888 if (@field(flags, @tagName(tag))) {
8889 return astgen.failNode(node, "redundant {s}", .{builtin_name});
8890 }
8891 @field(flags, @tagName(tag)) = true;
8892 },
8898 node = node_datas[node].lhs;
8899 } else {
8900 // 2 args
8901 if (info.param_count != 2) break;
8902
8903 switch (info.tag) {
8904 else => break,
8905 .field_parent_ptr => {
8906 if (flags.ptr_cast) break;
8907
8908 const flags_int: FlagsInt = @bitCast(flags);
8909 const cursor = maybeAdvanceSourceCursorToMainToken(gz, root_node);
8910 const parent_ptr_type = try ri.rl.resultTypeForCast(gz, root_node, "@alignCast");
8911 const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, node_datas[node].lhs);
8912 const field_ptr = try expr(gz, scope, .{ .rl = .none }, node_datas[node].rhs);
8913 try emitDbgStmt(gz, cursor);
8914 const result = try gz.addExtendedPayloadSmall(.field_parent_ptr, flags_int, Zir.Inst.FieldParentPtr{
8915 .src_node = gz.nodeIndexToRelative(node),
8916 .parent_ptr_type = parent_ptr_type,
8917 .field_name = field_name,
8918 .field_ptr = field_ptr,
8919 });
8920 return rvalue(gz, ri, result, root_node);
8921 },
8922 }
88938923 }
8894
8895 node = node_datas[node].lhs;
88968924 }
88978925
8898 const flags_i: u5 = @bitCast(flags);
8899 assert(flags_i != 0);
8926 const flags_int: FlagsInt = @bitCast(flags);
8927 assert(flags_int != 0);
89008928
89018929 const ptr_only: Zir.Inst.FullPtrCastFlags = .{ .ptr_cast = true };
8902 if (flags_i == @as(u5, @bitCast(ptr_only))) {
8930 if (flags_int == @as(FlagsInt, @bitCast(ptr_only))) {
89038931 // Special case: simpler representation
89048932 return typeCast(gz, scope, ri, root_node, node, .ptr_cast, "@ptrCast");
89058933 }
......@@ -8908,12 +8936,12 @@ fn ptrCast(
89088936 .const_cast = true,
89098937 .volatile_cast = true,
89108938 };
8911 if ((flags_i & ~@as(u5, @bitCast(no_result_ty_flags))) == 0) {
8939 if ((flags_int & ~@as(FlagsInt, @bitCast(no_result_ty_flags))) == 0) {
89128940 // Result type not needed
89138941 const cursor = maybeAdvanceSourceCursorToMainToken(gz, root_node);
89148942 const operand = try expr(gz, scope, .{ .rl = .none }, node);
89158943 try emitDbgStmt(gz, cursor);
8916 const result = try gz.addExtendedPayloadSmall(.ptr_cast_no_dest, flags_i, Zir.Inst.UnNode{
8944 const result = try gz.addExtendedPayloadSmall(.ptr_cast_no_dest, flags_int, Zir.Inst.UnNode{
89178945 .node = gz.nodeIndexToRelative(root_node),
89188946 .operand = operand,
89198947 });
......@@ -8926,7 +8954,7 @@ fn ptrCast(
89268954 const result_type = try ri.rl.resultTypeForCast(gz, root_node, flags.needResultTypeBuiltinName());
89278955 const operand = try expr(gz, scope, .{ .rl = .none }, node);
89288956 try emitDbgStmt(gz, cursor);
8929 const result = try gz.addExtendedPayloadSmall(.ptr_cast_full, flags_i, Zir.Inst.BinNode{
8957 const result = try gz.addExtendedPayloadSmall(.ptr_cast_full, flags_int, Zir.Inst.BinNode{
89308958 .node = gz.nodeIndexToRelative(root_node),
89318959 .lhs = result_type,
89328960 .rhs = operand,
......@@ -9379,7 +9407,7 @@ fn builtinCall(
93799407 try emitDbgNode(gz, node);
93809408
93819409 const result = try gz.addExtendedPayload(.error_cast, Zir.Inst.BinNode{
9382 .lhs = try ri.rl.resultTypeForCast(gz, node, "@errorCast"),
9410 .lhs = try ri.rl.resultTypeForCast(gz, node, builtin_name),
93839411 .rhs = try expr(gz, scope, .{ .rl = .none }, params[0]),
93849412 .node = gz.nodeIndexToRelative(node),
93859413 });
......@@ -9452,7 +9480,7 @@ fn builtinCall(
94529480 },
94539481
94549482 .splat => {
9455 const result_type = try ri.rl.resultTypeForCast(gz, node, "@splat");
9483 const result_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
94569484 const elem_type = try gz.addUnNode(.vector_elem_type, result_type, node);
94579485 const scalar = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, params[0]);
94589486 const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{
......@@ -9537,12 +9565,13 @@ fn builtinCall(
95379565 return rvalue(gz, ri, result, node);
95389566 },
95399567 .field_parent_ptr => {
9540 const parent_type = try typeExpr(gz, scope, params[0]);
9541 const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1]);
9542 const result = try gz.addPlNode(.field_parent_ptr, node, Zir.Inst.FieldParentPtr{
9543 .parent_type = parent_type,
9568 const parent_ptr_type = try ri.rl.resultTypeForCast(gz, node, builtin_name);
9569 const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0]);
9570 const result = try gz.addExtendedPayloadSmall(.field_parent_ptr, 0, Zir.Inst.FieldParentPtr{
9571 .src_node = gz.nodeIndexToRelative(node),
9572 .parent_ptr_type = parent_ptr_type,
95449573 .field_name = field_name,
9545 .field_ptr = try expr(gz, scope, .{ .rl = .none }, params[2]),
9574 .field_ptr = try expr(gz, scope, .{ .rl = .none }, params[1]),
95469575 });
95479576 return rvalue(gz, ri, result, node);
95489577 },
lib/std/zig/AstRlAnnotate.zig+1-1
......@@ -911,6 +911,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
911911 .work_item_id,
912912 .work_group_size,
913913 .work_group_id,
914 .field_parent_ptr,
914915 => {
915916 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
916917 return false;
......@@ -976,7 +977,6 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
976977 },
977978 .bit_offset_of,
978979 .offset_of,
979 .field_parent_ptr,
980980 .has_decl,
981981 .has_field,
982982 .field,
lib/std/zig/BuiltinFn.zig+1-1
......@@ -504,7 +504,7 @@ pub const list = list: {
504504 "@fieldParentPtr",
505505 .{
506506 .tag = .field_parent_ptr,
507 .param_count = 3,
507 .param_count = 2,
508508 },
509509 },
510510 .{
lib/std/zig/Zir.zig+12-7
......@@ -940,9 +940,6 @@ pub const Inst = struct {
940940 /// The addend communicates the type of the builtin.
941941 /// The mulends need to be coerced to the same type.
942942 mul_add,
943 /// Implements the `@fieldParentPtr` builtin.
944 /// Uses the `pl_node` union field with payload `FieldParentPtr`.
945 field_parent_ptr,
946943 /// Implements the `@memcpy` builtin.
947944 /// Uses the `pl_node` union field with payload `Bin`.
948945 memcpy,
......@@ -1230,7 +1227,6 @@ pub const Inst = struct {
12301227 .atomic_store,
12311228 .mul_add,
12321229 .builtin_call,
1233 .field_parent_ptr,
12341230 .max,
12351231 .memcpy,
12361232 .memset,
......@@ -1522,7 +1518,6 @@ pub const Inst = struct {
15221518 .atomic_rmw,
15231519 .mul_add,
15241520 .builtin_call,
1525 .field_parent_ptr,
15261521 .max,
15271522 .min,
15281523 .c_import,
......@@ -1794,7 +1789,6 @@ pub const Inst = struct {
17941789 .atomic_store = .pl_node,
17951790 .mul_add = .pl_node,
17961791 .builtin_call = .pl_node,
1797 .field_parent_ptr = .pl_node,
17981792 .max = .pl_node,
17991793 .memcpy = .pl_node,
18001794 .memset = .pl_node,
......@@ -2064,6 +2058,12 @@ pub const Inst = struct {
20642058 /// with a specific value. For instance, this is used for the capture of an `errdefer`.
20652059 /// This should never appear in a body.
20662060 value_placeholder,
2061 /// Implements the `@fieldParentPtr` builtin.
2062 /// `operand` is payload index to `FieldParentPtr`.
2063 /// `small` contains `FullPtrCastFlags`.
2064 /// Guaranteed to not have the `ptr_cast` flag.
2065 /// Uses the `pl_node` union field with payload `FieldParentPtr`.
2066 field_parent_ptr,
20672067
20682068 pub const InstData = struct {
20692069 opcode: Extended,
......@@ -3363,9 +3363,14 @@ pub const Inst = struct {
33633363 };
33643364
33653365 pub const FieldParentPtr = struct {
3366 parent_type: Ref,
3366 src_node: i32,
3367 parent_ptr_type: Ref,
33673368 field_name: Ref,
33683369 field_ptr: Ref,
3370
3371 pub fn src(self: FieldParentPtr) LazySrcLoc {
3372 return LazySrcLoc.nodeOffset(self.src_node);
3373 }
33693374 };
33703375
33713376 pub const Shuffle = struct {
src/Sema.zig+34-32
......@@ -1131,7 +1131,6 @@ fn analyzeBodyInner(
11311131 .atomic_rmw => try sema.zirAtomicRmw(block, inst),
11321132 .mul_add => try sema.zirMulAdd(block, inst),
11331133 .builtin_call => try sema.zirBuiltinCall(block, inst),
1134 .field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
11351134 .@"resume" => try sema.zirResume(block, inst),
11361135 .@"await" => try sema.zirAwait(block, inst),
11371136 .for_len => try sema.zirForLen(block, inst),
......@@ -1296,6 +1295,7 @@ fn analyzeBodyInner(
12961295 continue;
12971296 },
12981297 .value_placeholder => unreachable, // never appears in a body
1298 .field_parent_ptr => try sema.zirFieldParentPtr(block, extended),
12991299 };
13001300 },
13011301
......@@ -22757,10 +22757,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2275722757}
2275822758
2275922759fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
22760 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(
22761 @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?,
22762 @truncate(extended.small),
22763 ));
22760 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
22761 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
2276422762 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2276522763 const src = LazySrcLoc.nodeOffset(extra.node);
2276622764 const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node };
......@@ -22773,6 +22771,7 @@ fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDa
2277322771 operand,
2277422772 operand_src,
2277522773 dest_ty,
22774 flags.needResultTypeBuiltinName(),
2277622775 );
2277722776}
2277822777
......@@ -22791,6 +22790,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2279122790 operand,
2279222791 operand_src,
2279322792 dest_ty,
22793 "@ptrCast",
2279422794 );
2279522795}
2279622796
......@@ -22802,6 +22802,7 @@ fn ptrCastFull(
2280222802 operand: Air.Inst.Ref,
2280322803 operand_src: LazySrcLoc,
2280422804 dest_ty: Type,
22805 operation: []const u8,
2280522806) CompileError!Air.Inst.Ref {
2280622807 const mod = sema.mod;
2280722808 const operand_ty = sema.typeOf(operand);
......@@ -22834,7 +22835,7 @@ fn ptrCastFull(
2283422835 };
2283522836 const dest_elem_size = Type.fromInterned(dest_info.child).abiSize(mod);
2283622837 if (src_elem_size != dest_elem_size) {
22837 return sema.fail(block, src, "TODO: implement @ptrCast between slices changing the length", .{});
22838 return sema.fail(block, src, "TODO: implement {s} between slices changing the length", .{operation});
2283822839 }
2283922840 }
2284022841
......@@ -22983,7 +22984,7 @@ fn ptrCastFull(
2298322984 if (!flags.align_cast) {
2298422985 if (dest_align.compare(.gt, src_align)) {
2298522986 return sema.failWithOwnedErrorMsg(block, msg: {
22986 const msg = try sema.errMsg(block, src, "cast increases pointer alignment", .{});
22987 const msg = try sema.errMsg(block, src, "{s} increases pointer alignment", .{operation});
2298722988 errdefer msg.destroy(sema.gpa);
2298822989 try sema.errNote(block, operand_src, msg, "'{}' has alignment '{d}'", .{
2298922990 operand_ty.fmt(mod), src_align.toByteUnits() orelse 0,
......@@ -23000,7 +23001,7 @@ fn ptrCastFull(
2300023001 if (!flags.addrspace_cast) {
2300123002 if (src_info.flags.address_space != dest_info.flags.address_space) {
2300223003 return sema.failWithOwnedErrorMsg(block, msg: {
23003 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
23004 const msg = try sema.errMsg(block, src, "{s} changes pointer address space", .{operation});
2300423005 errdefer msg.destroy(sema.gpa);
2300523006 try sema.errNote(block, operand_src, msg, "'{}' has address space '{s}'", .{
2300623007 operand_ty.fmt(mod), @tagName(src_info.flags.address_space),
......@@ -23030,7 +23031,7 @@ fn ptrCastFull(
2303023031 if (!flags.const_cast) {
2303123032 if (src_info.flags.is_const and !dest_info.flags.is_const) {
2303223033 return sema.failWithOwnedErrorMsg(block, msg: {
23033 const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{});
23034 const msg = try sema.errMsg(block, src, "{s} discards const qualifier", .{operation});
2303423035 errdefer msg.destroy(sema.gpa);
2303523036 try sema.errNote(block, src, msg, "use @constCast to discard const qualifier", .{});
2303623037 break :msg msg;
......@@ -23041,7 +23042,7 @@ fn ptrCastFull(
2304123042 if (!flags.volatile_cast) {
2304223043 if (src_info.flags.is_volatile and !dest_info.flags.is_volatile) {
2304323044 return sema.failWithOwnedErrorMsg(block, msg: {
23044 const msg = try sema.errMsg(block, src, "cast discards volatile qualifier", .{});
23045 const msg = try sema.errMsg(block, src, "{s} discards volatile qualifier", .{operation});
2304523046 errdefer msg.destroy(sema.gpa);
2304623047 try sema.errNote(block, src, msg, "use @volatileCast to discard volatile qualifier", .{});
2304723048 break :msg msg;
......@@ -23187,10 +23188,8 @@ fn ptrCastFull(
2318723188
2318823189fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
2318923190 const mod = sema.mod;
23190 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(
23191 @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?,
23192 @truncate(extended.small),
23193 ));
23191 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
23192 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
2319423193 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
2319523194 const src = LazySrcLoc.nodeOffset(extra.node);
2319623195 const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node };
......@@ -24859,25 +24858,28 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2485924858 );
2486024859}
2486124860
24862fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24861fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
2486324862 const mod = sema.mod;
2486424863 const ip = &mod.intern_pool;
2486524864
24866 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
24867 const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, inst_data.payload_index).data;
24868 const inst_src = inst_data.src();
24869 const parent_ptr_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
24870 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
24871 const field_ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node };
24872
24873 const parent_ptr_ty = try sema.resolveType(block, parent_ptr_ty_src, extra.parent_type);
24874 try sema.checkPtrType(block, parent_ptr_ty_src, parent_ptr_ty, false);
24875 if (!parent_ptr_ty.isSinglePointer(mod)) {
24876 return sema.fail(block, parent_ptr_ty_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(sema.mod)});
24877 }
24878 const parent_ty = parent_ptr_ty.childType(mod);
24879 if (parent_ty.zigTypeTag(mod) != .Struct and parent_ty.zigTypeTag(mod) != .Union) {
24880 return sema.fail(block, parent_ptr_ty_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(sema.mod)});
24865 const extra = sema.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;
24866 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
24867 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
24868 assert(!flags.ptr_cast);
24869 const inst_src = extra.src();
24870 const field_name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.src_node };
24871 const field_ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.src_node };
24872
24873 const parent_ptr_ty = try sema.resolveDestType(block, inst_src, extra.parent_ptr_type, .remove_eu, "@fieldParentPtr");
24874 try sema.checkPtrType(block, inst_src, parent_ptr_ty, true);
24875 const parent_ptr_info = parent_ptr_ty.ptrInfo(mod);
24876 if (parent_ptr_info.flags.size != .One) {
24877 return sema.fail(block, inst_src, "expected single pointer type, found '{}'", .{parent_ptr_ty.fmt(sema.mod)});
24878 }
24879 const parent_ty = Type.fromInterned(parent_ptr_info.child);
24880 switch (parent_ty.zigTypeTag(mod)) {
24881 .Struct, .Union => {},
24882 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(sema.mod)}),
2488124883 }
2488224884 try sema.resolveTypeLayout(parent_ty);
2488324885
......@@ -24916,7 +24918,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2491624918 .is_allowzero = field_ptr_info.flags.is_allowzero,
2491724919 .address_space = field_ptr_info.flags.address_space,
2491824920 },
24919 .packed_offset = parent_ptr_ty.ptrInfo(mod).packed_offset,
24921 .packed_offset = parent_ptr_info.packed_offset,
2492024922 };
2492124923 const field_ty = parent_ty.structFieldType(field_index, mod);
2492224924 var actual_field_ptr_info: InternPool.Key.PtrType = .{
......@@ -25000,7 +25002,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2500025002 } },
2500125003 });
2500225004 };
25003 return sema.coerce(block, parent_ptr_ty, result, inst_src);
25005 return sema.ptrCastFull(block, flags, inst_src, result, inst_src, parent_ptr_ty, "@fieldParentPtr");
2500425006}
2500525007
2500625008fn zirMinMax(
src/print_zir.zig+15-8
......@@ -355,7 +355,6 @@ const Writer = struct {
355355 .atomic_rmw => try self.writeAtomicRmw(stream, inst),
356356 .shuffle => try self.writeShuffle(stream, inst),
357357 .mul_add => try self.writeMulAdd(stream, inst),
358 .field_parent_ptr => try self.writeFieldParentPtr(stream, inst),
359358 .builtin_call => try self.writeBuiltinCall(stream, inst),
360359
361360 .field_type_ref => try self.writeFieldTypeRef(stream, inst),
......@@ -609,6 +608,7 @@ const Writer = struct {
609608
610609 .restore_err_ret_index => try self.writeRestoreErrRetIndex(stream, extended),
611610 .closure_get => try self.writeClosureGet(stream, extended),
611 .field_parent_ptr => try self.writeFieldParentPtr(stream, extended),
612612 }
613613 }
614614
......@@ -901,16 +901,21 @@ const Writer = struct {
901901 try self.writeSrc(stream, inst_data.src());
902902 }
903903
904 fn writeFieldParentPtr(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
905 const inst_data = self.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
906 const extra = self.code.extraData(Zir.Inst.FieldParentPtr, inst_data.payload_index).data;
907 try self.writeInstRef(stream, extra.parent_type);
904 fn writeFieldParentPtr(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
905 const extra = self.code.extraData(Zir.Inst.FieldParentPtr, extended.operand).data;
906 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
907 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
908 if (flags.align_cast) try stream.writeAll("align_cast, ");
909 if (flags.addrspace_cast) try stream.writeAll("addrspace_cast, ");
910 if (flags.const_cast) try stream.writeAll("const_cast, ");
911 if (flags.volatile_cast) try stream.writeAll("volatile_cast, ");
912 try self.writeInstRef(stream, extra.parent_ptr_type);
908913 try stream.writeAll(", ");
909914 try self.writeInstRef(stream, extra.field_name);
910915 try stream.writeAll(", ");
911916 try self.writeInstRef(stream, extra.field_ptr);
912917 try stream.writeAll(") ");
913 try self.writeSrc(stream, inst_data.src());
918 try self.writeSrc(stream, extra.src());
914919 }
915920
916921 fn writeBuiltinAsyncCall(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
......@@ -1069,7 +1074,8 @@ const Writer = struct {
10691074 }
10701075
10711076 fn writePtrCastFull(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1072 const flags = @as(Zir.Inst.FullPtrCastFlags, @bitCast(@as(u5, @truncate(extended.small))));
1077 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
1078 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
10731079 const extra = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
10741080 const src = LazySrcLoc.nodeOffset(extra.node);
10751081 if (flags.ptr_cast) try stream.writeAll("ptr_cast, ");
......@@ -1085,7 +1091,8 @@ const Writer = struct {
10851091 }
10861092
10871093 fn writePtrCastNoDest(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1088 const flags = @as(Zir.Inst.FullPtrCastFlags, @bitCast(@as(u5, @truncate(extended.small))));
1094 const FlagsInt = @typeInfo(Zir.Inst.FullPtrCastFlags).Struct.backing_integer.?;
1095 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(FlagsInt, @truncate(extended.small)));
10891096 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
10901097 const src = LazySrcLoc.nodeOffset(extra.node);
10911098 if (flags.const_cast) try stream.writeAll("const_cast, ");
test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig+1-1
......@@ -8,7 +8,7 @@ export fn entry() u32 {
88// backend=stage2
99// target=native
1010//
11// :3:23: error: cast increases pointer alignment
11// :3:23: error: @ptrCast increases pointer alignment
1212// :3:32: note: '*u8' has alignment '1'
1313// :3:23: note: '*u32' has alignment '4'
1414// :3:23: note: use @alignCast to assert pointer alignment
test/cases/compile_errors/nested_ptr_cast_bad_operand.zig+1-1
......@@ -16,7 +16,7 @@ export fn c() void {
1616//
1717// :3:45: error: null pointer casted to type '*const u32'
1818// :6:34: error: expected pointer type, found 'comptime_int'
19// :9:22: error: cast increases pointer alignment
19// :9:22: error: @ptrCast increases pointer alignment
2020// :9:71: note: '?*const u8' has alignment '1'
2121// :9:22: note: '?*f32' has alignment '4'
2222// :9:22: note: use @alignCast to assert pointer alignment
test/cases/compile_errors/ptrCast_discards_const_qualifier.zig+1-1
......@@ -8,5 +8,5 @@ export fn entry() void {
88// backend=stage2
99// target=native
1010//
11// :3:21: error: cast discards const qualifier
11// :3:21: error: @ptrCast discards const qualifier
1212// :3:21: note: use @constCast to discard const qualifier