authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-06-25 02:26:48+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-06-25 13:28:32+01:00
log569ae762e1025f83ae7d2c6ae2ca6b015b289991
tree77c104934f7d621375b047cfc1728628a3abacbc
parent8afadee45a7a7ea8e456b5917db4fbfdd140b555
signaturelock-open Commit is signed but in an unrecognized format.

compiler: allow cast builtins to coerce result to error union or optional

Also improves some error messages

4 files changed, 93 insertions(+), 25 deletions(-)

src/AstGen.zig+1-9
......@@ -8050,17 +8050,9 @@ fn ptrCast(
80508050 }
80518051
80528052 // Full cast including result type
8053 const need_result_type_builtin = if (flags.ptr_cast)
8054 "@ptrCast"
8055 else if (flags.align_cast)
8056 "@alignCast"
8057 else if (flags.addrspace_cast)
8058 "@addrSpaceCast"
8059 else
8060 unreachable;
80618053
80628054 const cursor = maybeAdvanceSourceCursorToMainToken(gz, root_node);
8063 const result_type = try ri.rl.resultType(gz, root_node, need_result_type_builtin);
8055 const result_type = try ri.rl.resultType(gz, root_node, flags.needResultTypeBuiltinName());
80648056 const operand = try expr(gz, scope, .{ .rl = .none }, node);
80658057 try emitDbgStmt(gz, cursor);
80668058 const result = try gz.addExtendedPayloadSmall(.ptr_cast_full, flags_i, Zir.Inst.BinNode{
src/Module.zig+40
......@@ -34,6 +34,7 @@ const isUpDir = @import("introspect.zig").isUpDir;
3434const clang = @import("clang.zig");
3535const InternPool = @import("InternPool.zig");
3636const Alignment = InternPool.Alignment;
37const BuiltinFn = @import("BuiltinFn.zig");
3738
3839comptime {
3940 @setEvalBranchQuota(4000);
......@@ -2273,6 +2274,41 @@ pub const SrcLoc = struct {
22732274 .node_offset_builtin_call_arg3 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 3),
22742275 .node_offset_builtin_call_arg4 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 4),
22752276 .node_offset_builtin_call_arg5 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 5),
2277 .node_offset_ptrcast_operand => |node_off| {
2278 const tree = try src_loc.file_scope.getTree(gpa);
2279 const main_tokens = tree.nodes.items(.main_token);
2280 const node_datas = tree.nodes.items(.data);
2281 const node_tags = tree.nodes.items(.tag);
2282
2283 var node = src_loc.declRelativeToNodeIndex(node_off);
2284 while (true) {
2285 switch (node_tags[node]) {
2286 .builtin_call_two, .builtin_call_two_comma => {},
2287 else => break,
2288 }
2289
2290 if (node_datas[node].lhs == 0) break; // 0 args
2291 if (node_datas[node].rhs != 0) break; // 2 args
2292
2293 const builtin_token = main_tokens[node];
2294 const builtin_name = tree.tokenSlice(builtin_token);
2295 const info = BuiltinFn.list.get(builtin_name) orelse break;
2296
2297 switch (info.tag) {
2298 else => break,
2299 .ptr_cast,
2300 .align_cast,
2301 .addrspace_cast,
2302 .const_cast,
2303 .volatile_cast,
2304 => {},
2305 }
2306
2307 node = node_datas[node].lhs;
2308 }
2309
2310 return nodeToSpan(tree, node);
2311 },
22762312 .node_offset_array_access_index => |node_off| {
22772313 const tree = try src_loc.file_scope.getTree(gpa);
22782314 const node_datas = tree.nodes.items(.data);
......@@ -2887,6 +2923,9 @@ pub const LazySrcLoc = union(enum) {
28872923 node_offset_builtin_call_arg3: i32,
28882924 node_offset_builtin_call_arg4: i32,
28892925 node_offset_builtin_call_arg5: i32,
2926 /// Like `node_offset_builtin_call_arg0` but recurses through arbitrarily many calls
2927 /// to pointer cast builtins.
2928 node_offset_ptrcast_operand: i32,
28902929 /// The source location points to the index expression of an array access
28912930 /// expression, found by taking this AST node index offset from the containing
28922931 /// Decl AST node, which points to an array access AST node. Next, navigate
......@@ -3145,6 +3184,7 @@ pub const LazySrcLoc = union(enum) {
31453184 .node_offset_builtin_call_arg3,
31463185 .node_offset_builtin_call_arg4,
31473186 .node_offset_builtin_call_arg5,
3187 .node_offset_ptrcast_operand,
31483188 .node_offset_array_access_index,
31493189 .node_offset_slice_ptr,
31503190 .node_offset_slice_start,
src/Sema.zig+45-16
......@@ -1820,8 +1820,25 @@ pub fn resolveType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Ins
18201820 return ty;
18211821}
18221822
1823fn resolveCastDestType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref, builtin_name: []const u8) !Type {
1824 return sema.resolveType(block, src, zir_ref) catch |err| switch (err) {
1823fn resolveCastDestType(
1824 sema: *Sema,
1825 block: *Block,
1826 src: LazySrcLoc,
1827 zir_ref: Zir.Inst.Ref,
1828 strat: enum { remove_eu_opt, remove_eu, remove_opt },
1829 builtin_name: []const u8,
1830) !Type {
1831 const mod = sema.mod;
1832 const remove_eu = switch (strat) {
1833 .remove_eu_opt, .remove_eu => true,
1834 .remove_opt => false,
1835 };
1836 const remove_opt = switch (strat) {
1837 .remove_eu_opt, .remove_opt => true,
1838 .remove_eu => false,
1839 };
1840
1841 const raw_ty = sema.resolveType(block, src, zir_ref) catch |err| switch (err) {
18251842 error.GenericPoison => {
18261843 // Cast builtins use their result type as the destination type, but
18271844 // it could be an anytype argument, which we can't catch in AstGen.
......@@ -1836,6 +1853,18 @@ fn resolveCastDestType(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir
18361853 },
18371854 else => |e| return e,
18381855 };
1856
1857 if (remove_eu and raw_ty.zigTypeTag(mod) == .ErrorUnion) {
1858 const eu_child = raw_ty.errorUnionPayload(mod);
1859 if (remove_opt and eu_child.zigTypeTag(mod) == .Optional) {
1860 return eu_child.childType(mod);
1861 }
1862 return eu_child;
1863 }
1864 if (remove_opt and raw_ty.zigTypeTag(mod) == .Optional) {
1865 return raw_ty.childType(mod);
1866 }
1867 return raw_ty;
18391868}
18401869
18411870fn analyzeAsType(
......@@ -8304,7 +8333,7 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
83048333 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
83058334 const src = inst_data.src();
83068335 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
8307 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@enumFromInt");
8336 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@enumFromInt");
83088337 const operand = try sema.resolveInst(extra.rhs);
83098338
83108339 if (dest_ty.zigTypeTag(mod) != .Enum) {
......@@ -9600,7 +9629,7 @@ fn zirIntCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
96009629 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
96019630 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
96029631
9603 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@intCast");
9632 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@intCast");
96049633 const operand = try sema.resolveInst(extra.rhs);
96059634
96069635 return sema.intCast(block, inst_data.src(), dest_ty, src, operand, operand_src, true);
......@@ -9761,7 +9790,7 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
97619790 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
97629791 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
97639792
9764 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@bitCast");
9793 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@bitCast");
97659794 const operand = try sema.resolveInst(extra.rhs);
97669795 const operand_ty = sema.typeOf(operand);
97679796 switch (dest_ty.zigTypeTag(mod)) {
......@@ -9904,7 +9933,7 @@ fn zirFloatCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
99049933 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
99059934 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
99069935
9907 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@floatCast");
9936 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@floatCast");
99089937 const operand = try sema.resolveInst(extra.rhs);
99099938
99109939 const target = mod.getTarget();
......@@ -20706,7 +20735,7 @@ fn zirIntFromFloat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2070620735 const src = inst_data.src();
2070720736 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2070820737 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
20709 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@intFromFloat");
20738 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@intFromFloat");
2071020739 const operand = try sema.resolveInst(extra.rhs);
2071120740 const operand_ty = sema.typeOf(operand);
2071220741
......@@ -20746,7 +20775,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2074620775 const src = inst_data.src();
2074720776 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
2074820777 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
20749 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@floatFromInt");
20778 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@floatFromInt");
2075020779 const operand = try sema.resolveInst(extra.rhs);
2075120780 const operand_ty = sema.typeOf(operand);
2075220781
......@@ -20775,7 +20804,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2077520804 const operand_res = try sema.resolveInst(extra.rhs);
2077620805 const operand_coerced = try sema.coerce(block, Type.usize, operand_res, operand_src);
2077720806
20778 const ptr_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@ptrFromInt");
20807 const ptr_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu, "@ptrFromInt");
2077920808 try sema.checkPtrType(block, src, ptr_ty);
2078020809 const elem_ty = ptr_ty.elemType2(mod);
2078120810 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema);
......@@ -20833,7 +20862,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2083320862 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2083420863 const src = LazySrcLoc.nodeOffset(extra.node);
2083520864 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
20836 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@errSetCast");
20865 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@errSetCast");
2083720866 const operand = try sema.resolveInst(extra.rhs);
2083820867 const operand_ty = sema.typeOf(operand);
2083920868 try sema.checkErrorSetType(block, src, dest_ty);
......@@ -20915,12 +20944,12 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
2091520944}
2091620945
2091720946fn zirPtrCastFull(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
20918 const flags = @as(Zir.Inst.FullPtrCastFlags, @bitCast(@as(u5, @truncate(extended.small))));
20947 const flags: Zir.Inst.FullPtrCastFlags = @bitCast(@as(u5, @truncate(extended.small)));
2091920948 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2092020949 const src = LazySrcLoc.nodeOffset(extra.node);
20921 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
20950 const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node };
2092220951 const operand = try sema.resolveInst(extra.rhs);
20923 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@ptrCast"); // TODO: better error message (builtin name)
20952 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu, flags.needResultTypeBuiltinName());
2092420953 return sema.ptrCastFull(
2092520954 block,
2092620955 flags,
......@@ -20936,7 +20965,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2093620965 const src = inst_data.src();
2093720966 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2093820967 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
20939 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@ptrCast");
20968 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu, "@ptrCast");
2094020969 const operand = try sema.resolveInst(extra.rhs);
2094120970
2094220971 return sema.ptrCastFull(
......@@ -21325,7 +21354,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2132521354 const flags = @as(Zir.Inst.FullPtrCastFlags, @bitCast(@as(u5, @truncate(extended.small))));
2132621355 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
2132721356 const src = LazySrcLoc.nodeOffset(extra.node);
21328 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
21357 const operand_src: LazySrcLoc = .{ .node_offset_ptrcast_operand = extra.node };
2132921358 const operand = try sema.resolveInst(extra.operand);
2133021359 const operand_ty = sema.typeOf(operand);
2133121360 try sema.checkPtrOperand(block, operand_src, operand_ty);
......@@ -21349,7 +21378,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2134921378 const src = inst_data.src();
2135021379 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
2135121380 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
21352 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, "@truncate");
21381 const dest_ty = try sema.resolveCastDestType(block, src, extra.lhs, .remove_eu_opt, "@truncate");
2135321382 const dest_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, dest_ty, src);
2135421383 const operand = try sema.resolveInst(extra.rhs);
2135521384 const operand_ty = sema.typeOf(operand);
src/Zir.zig+7
......@@ -2820,6 +2820,13 @@ pub const Inst = struct {
28202820 addrspace_cast: bool = false,
28212821 const_cast: bool = false,
28222822 volatile_cast: bool = false,
2823
2824 pub inline fn needResultTypeBuiltinName(flags: FullPtrCastFlags) []const u8 {
2825 if (flags.ptr_cast) return "@ptrCast";
2826 if (flags.align_cast) return "@alignCast";
2827 if (flags.addrspace_cast) return "@addrSpaceCast";
2828 unreachable;
2829 }
28232830 };
28242831
28252832 /// Trailing: