authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-29 22:50:53-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-04-29 22:50:53-04:00
logcc39d453c45645296cd771c94d97b8a77469be91
tree8d9c857255ac15fe2f8125789f8a42a7a03573eb
parenta0a2ce92ca129d28e22c63f7bace1672c43776b5
parent596f7df02e78adf334eed4a1f14eafa31ca611b9
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11549 from Vexu/stage2-fixes

Stage2: fix comptime unreachable, adjust Zir.Extended

8 files changed, 283 insertions(+), 245 deletions(-)

src/AstGen.zig+73-41
......@@ -72,6 +72,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void {
7272 i32 => @bitCast(u32, @field(extra, field.name)),
7373 Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)),
7474 Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)),
75 Zir.Inst.ExtendedFunc.Bits => @bitCast(u32, @field(extra, field.name)),
7576 else => @compileError("bad field type"),
7677 };
7778 i += 1;
......@@ -740,7 +741,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
740741 _ = try gz.addAsIndex(.{
741742 .tag = .@"unreachable",
742743 .data = .{ .@"unreachable" = .{
743 .safety = true,
744 .force_comptime = gz.force_comptime,
744745 .src_node = gz.nodeIndexToRelative(node),
745746 } },
746747 });
......@@ -1078,8 +1079,14 @@ fn awaitExpr(
10781079 });
10791080 }
10801081 const operand = try expr(gz, scope, .none, rhs_node);
1081 const tag: Zir.Inst.Tag = if (gz.nosuspend_node != 0) .await_nosuspend else .@"await";
1082 const result = try gz.addUnNode(tag, operand, node);
1082 const result = if (gz.nosuspend_node != 0)
1083 try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{
1084 .node = gz.nodeIndexToRelative(node),
1085 .operand = operand,
1086 })
1087 else
1088 try gz.addUnNode(.@"await", operand, node);
1089
10831090 return rvalue(gz, rl, result, node);
10841091}
10851092
......@@ -2239,6 +2246,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
22392246 .field_val_named,
22402247 .func,
22412248 .func_inferred,
2249 .func_extended,
22422250 .int,
22432251 .int_big,
22442252 .float,
......@@ -2349,7 +2357,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
23492357 .int_to_ptr,
23502358 .float_cast,
23512359 .int_cast,
2352 .err_set_cast,
23532360 .ptr_cast,
23542361 .truncate,
23552362 .align_cast,
......@@ -2386,15 +2393,24 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
23862393 .c_import,
23872394 .@"resume",
23882395 .@"await",
2389 .await_nosuspend,
23902396 .ret_err_value_code,
2391 .extended,
23922397 .closure_get,
23932398 .array_base_ptr,
23942399 .field_base_ptr,
23952400 .param_type,
2401 .ret_ptr,
2402 .ret_type,
23962403 => break :b false,
23972404
2405 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {
2406 .breakpoint,
2407 .fence,
2408 .set_align_stack,
2409 .set_float_mode,
2410 => break :b true,
2411 else => break :b false,
2412 },
2413
23982414 // ZIR instructions that are always `noreturn`.
23992415 .@"break",
24002416 .break_inline,
......@@ -2415,11 +2431,11 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
24152431 },
24162432
24172433 // ZIR instructions that are always `void`.
2418 .breakpoint,
2419 .fence,
24202434 .dbg_stmt,
24212435 .dbg_var_ptr,
24222436 .dbg_var_val,
2437 .dbg_block_begin,
2438 .dbg_block_end,
24232439 .ensure_result_used,
24242440 .ensure_result_non_error,
24252441 .@"export",
......@@ -2436,9 +2452,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
24362452 .validate_struct_init_comptime,
24372453 .validate_array_init,
24382454 .validate_array_init_comptime,
2439 .set_align_stack,
24402455 .set_cold,
2441 .set_float_mode,
24422456 .set_runtime_safety,
24432457 .closure_capture,
24442458 .memcpy,
......@@ -6310,9 +6324,9 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
63106324 }
63116325
63126326 const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{
6313 .ptr = try gz.addNodeExtended(.ret_ptr, node),
6327 .ptr = try gz.addNode(.ret_ptr, node),
63146328 } else .{
6315 .ty = try gz.addNodeExtended(.ret_type, node),
6329 .ty = try gz.addNode(.ret_type, node),
63166330 };
63176331 const prev_anon_name_strategy = gz.anon_name_strategy;
63186332 gz.anon_name_strategy = .func;
......@@ -7183,7 +7197,26 @@ fn builtinCall(
71837197 },
71847198 .fence => {
71857199 const order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[0]);
7186 const result = try gz.addUnNode(.fence, order, node);
7200 const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{
7201 .node = gz.nodeIndexToRelative(node),
7202 .operand = order,
7203 });
7204 return rvalue(gz, rl, result, node);
7205 },
7206 .set_float_mode => {
7207 const order = try expr(gz, scope, .{ .coerced_ty = .float_mode_type }, params[0]);
7208 const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{
7209 .node = gz.nodeIndexToRelative(node),
7210 .operand = order,
7211 });
7212 return rvalue(gz, rl, result, node);
7213 },
7214 .set_align_stack => {
7215 const order = try expr(gz, scope, align_rl, params[0]);
7216 const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
7217 .node = gz.nodeIndexToRelative(node),
7218 .operand = order,
7219 });
71877220 return rvalue(gz, rl, result, node);
71887221 },
71897222
......@@ -7198,14 +7231,13 @@ fn builtinCall(
71987231 return rvalue(gz, rl, result, node);
71997232 },
72007233
7201 .breakpoint => return simpleNoOpVoid(gz, rl, node, .breakpoint),
7202
72037234 // zig fmt: off
72047235 .This => return rvalue(gz, rl, try gz.addNodeExtended(.this, node), node),
72057236 .return_address => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr, node), node),
72067237 .error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node),
72077238 .frame => return rvalue(gz, rl, try gz.addNodeExtended(.frame, node), node),
72087239 .frame_address => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address, node), node),
7240 .breakpoint => return rvalue(gz, rl, try gz.addNodeExtended(.breakpoint, node), node),
72097241
72107242 .type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info),
72117243 .size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of),
......@@ -7222,9 +7254,7 @@ fn builtinCall(
72227254 .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file),
72237255 .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name),
72247256 .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .panic),
7225 .set_align_stack => return simpleUnOp(gz, scope, rl, node, align_rl, params[0], .set_align_stack),
72267257 .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold),
7227 .set_float_mode => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .float_mode_type }, params[0], .set_float_mode),
72287258 .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety),
72297259 .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt),
72307260 .sin => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sin),
......@@ -7252,7 +7282,6 @@ fn builtinCall(
72527282 .int_to_enum => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum),
72537283 .float_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast),
72547284 .int_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast),
7255 .err_set_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .err_set_cast),
72567285 .ptr_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast),
72577286 .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate),
72587287 // zig fmt: on
......@@ -7266,6 +7295,14 @@ fn builtinCall(
72667295 });
72677296 return rvalue(gz, rl, result, node);
72687297 },
7298 .err_set_cast => {
7299 const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{
7300 .lhs = try typeExpr(gz, scope, params[0]),
7301 .rhs = try expr(gz, scope, .none, params[1]),
7302 .node = gz.nodeIndexToRelative(node),
7303 });
7304 return rvalue(gz, rl, result, node);
7305 },
72697306
72707307 // zig fmt: off
72717308 .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl),
......@@ -8940,7 +8977,8 @@ fn rvalue(
89408977 const result = r: {
89418978 if (refToIndex(raw_result)) |result_index| {
89428979 const zir_tags = gz.astgen.instructions.items(.tag);
8943 if (zir_tags[result_index].isAlwaysVoid()) {
8980 const data = gz.astgen.instructions.items(.data)[result_index];
8981 if (zir_tags[result_index].isAlwaysVoid(data)) {
89448982 break :r Zir.Inst.Ref.void_value;
89458983 }
89468984 }
......@@ -9987,10 +10025,18 @@ const GenZir = struct {
998710025 @boolToInt(args.cc != .none),
998810026 );
998910027 const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{
9990 .src_node = gz.nodeIndexToRelative(args.src_node),
999110028 .param_block = args.param_block,
999210029 .ret_body_len = @intCast(u32, ret_ty.len),
999310030 .body_len = @intCast(u32, body.len),
10031 .bits = .{
10032 .is_var_args = args.is_var_args,
10033 .is_inferred_error = args.is_inferred_error,
10034 .has_lib_name = args.lib_name != 0,
10035 .has_cc = args.cc != .none,
10036 .has_align = args.align_inst != .none,
10037 .is_test = args.is_test,
10038 .is_extern = args.is_extern,
10039 },
999410040 });
999510041 if (args.lib_name != 0) {
999610042 astgen.extra.appendAssumeCapacity(args.lib_name);
......@@ -10014,19 +10060,10 @@ const GenZir = struct {
1001410060 astgen.instructions.items(.data)[args.ret_br].@"break".block_inst = new_index;
1001510061 }
1001610062 astgen.instructions.appendAssumeCapacity(.{
10017 .tag = .extended,
10018 .data = .{ .extended = .{
10019 .opcode = .func,
10020 .small = @bitCast(u16, Zir.Inst.ExtendedFunc.Small{
10021 .is_var_args = args.is_var_args,
10022 .is_inferred_error = args.is_inferred_error,
10023 .has_lib_name = args.lib_name != 0,
10024 .has_cc = args.cc != .none,
10025 .has_align = args.align_inst != .none,
10026 .is_test = args.is_test,
10027 .is_extern = args.is_extern,
10028 }),
10029 .operand = payload_index,
10063 .tag = .func_extended,
10064 .data = .{ .pl_node = .{
10065 .src_node = gz.nodeIndexToRelative(args.src_node),
10066 .payload_index = payload_index,
1003010067 } },
1003110068 });
1003210069 gz.instructions.appendAssumeCapacity(new_index);
......@@ -10893,9 +10930,7 @@ const GenZir = struct {
1089310930 fn addDbgBlockBegin(gz: *GenZir) !void {
1089410931 if (gz.force_comptime) return;
1089510932
10896 _ = try gz.add(.{ .tag = .extended, .data = .{
10897 .extended = .{ .opcode = .dbg_block_begin, .small = undefined, .operand = undefined },
10898 } });
10933 _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined });
1089910934 }
1090010935
1090110936 fn addDbgBlockEnd(gz: *GenZir) !void {
......@@ -10903,18 +10938,15 @@ const GenZir = struct {
1090310938 const gpa = gz.astgen.gpa;
1090410939
1090510940 const tags = gz.astgen.instructions.items(.tag);
10906 const data = gz.astgen.instructions.items(.data);
1090710941 const last_inst = gz.instructions.items[gz.instructions.items.len - 1];
1090810942 // remove dbg_block_begin immediately followed by dbg_block_end
10909 if (tags[last_inst] == .extended and data[last_inst].extended.opcode == .dbg_block_begin) {
10943 if (tags[last_inst] == .dbg_block_begin) {
1091010944 _ = gz.instructions.pop();
1091110945 return;
1091210946 }
1091310947
1091410948 const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
10915 try gz.astgen.instructions.append(gpa, .{ .tag = .extended, .data = .{
10916 .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
10917 } });
10949 try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });
1091810950 try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index);
1091910951 }
1092010952
src/Module.zig+4-4
......@@ -1532,10 +1532,10 @@ pub const Fn = struct {
15321532 switch (zir_tags[func.zir_body_inst]) {
15331533 .func => return false,
15341534 .func_inferred => return true,
1535 .extended => {
1536 const extended = zir.instructions.items(.data)[func.zir_body_inst].extended;
1537 const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
1538 return small.is_inferred_error;
1535 .func_extended => {
1536 const inst_data = zir.instructions.items(.data)[func.zir_body_inst].pl_node;
1537 const extra = zir.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
1538 return extra.data.bits.is_inferred_error;
15391539 },
15401540 else => unreachable,
15411541 }
src/Sema.zig+89-91
......@@ -745,6 +745,7 @@ fn analyzeBodyInner(
745745 .field_call_bind => try sema.zirFieldCallBind(block, inst),
746746 .func => try sema.zirFunc(block, inst, false),
747747 .func_inferred => try sema.zirFunc(block, inst, true),
748 .func_extended => try sema.zirFuncExtended(block, inst),
748749 .import => try sema.zirImport(block, inst),
749750 .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst),
750751 .int => try sema.zirInt(block, inst),
......@@ -819,7 +820,6 @@ fn analyzeBodyInner(
819820 .int_to_ptr => try sema.zirIntToPtr(block, inst),
820821 .float_cast => try sema.zirFloatCast(block, inst),
821822 .int_cast => try sema.zirIntCast(block, inst),
822 .err_set_cast => try sema.zirErrSetCast(block, inst),
823823 .ptr_cast => try sema.zirPtrCast(block, inst),
824824 .truncate => try sema.zirTruncate(block, inst),
825825 .align_cast => try sema.zirAlignCast(block, inst),
......@@ -842,8 +842,7 @@ fn analyzeBodyInner(
842842 .field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
843843 .builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst),
844844 .@"resume" => try sema.zirResume(block, inst),
845 .@"await" => try sema.zirAwait(block, inst, false),
846 .await_nosuspend => try sema.zirAwait(block, inst, true),
845 .@"await" => try sema.zirAwait(block, inst),
847846 .array_base_ptr => try sema.zirArrayBasePtr(block, inst),
848847 .field_base_ptr => try sema.zirFieldBasePtr(block, inst),
849848
......@@ -894,6 +893,9 @@ fn analyzeBodyInner(
894893 .shl_exact => try sema.zirShl(block, inst, .shl_exact),
895894 .shl_sat => try sema.zirShl(block, inst, .shl_sat),
896895
896 .ret_ptr => try sema.zirRetPtr(block, inst),
897 .ret_type => try sema.zirRetType(block, inst),
898
897899 // Instructions that we know to *always* be noreturn based solely on their tag.
898900 // These functions match the return type of analyzeBody so that we can
899901 // tail call them here.
......@@ -910,14 +912,11 @@ fn analyzeBodyInner(
910912 const extended = datas[inst].extended;
911913 break :ext switch (extended.opcode) {
912914 // zig fmt: off
913 .func => try sema.zirFuncExtended( block, extended, inst),
914915 .variable => try sema.zirVarExtended( block, extended),
915916 .struct_decl => try sema.zirStructDecl( block, extended, inst),
916917 .enum_decl => try sema.zirEnumDecl( block, extended),
917918 .union_decl => try sema.zirUnionDecl( block, extended, inst),
918919 .opaque_decl => try sema.zirOpaqueDecl( block, extended),
919 .ret_ptr => try sema.zirRetPtr( block, extended),
920 .ret_type => try sema.zirRetType( block, extended),
921920 .this => try sema.zirThis( block, extended),
922921 .ret_addr => try sema.zirRetAddr( block, extended),
923922 .builtin_src => try sema.zirBuiltinSrc( block, extended),
......@@ -940,16 +939,28 @@ fn analyzeBodyInner(
940939 .wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
941940 .prefetch => try sema.zirPrefetch( block, extended),
942941 .field_call_bind_named => try sema.zirFieldCallBindNamed(block, extended),
942 .err_set_cast => try sema.zirErrSetCast( block, extended),
943 .await_nosuspend => try sema.zirAwaitNosuspend( block, extended),
943944 // zig fmt: on
944 .dbg_block_begin => {
945 dbg_block_begins += 1;
946 try sema.zirDbgBlockBegin(block);
945 .fence => {
946 try sema.zirFence(block, extended);
947 i += 1;
948 continue;
949 },
950 .set_float_mode => {
951 try sema.zirSetFloatMode(block, extended);
947952 i += 1;
948953 continue;
949954 },
950 .dbg_block_end => {
951 dbg_block_begins -= 1;
952 try sema.zirDbgBlockEnd(block);
955 .set_align_stack => {
956 try sema.zirSetAlignStack(block, extended);
957 i += 1;
958 continue;
959 },
960 .breakpoint => {
961 if (!block.is_comptime) {
962 _ = try block.addNoOp(.breakpoint);
963 }
953964 i += 1;
954965 continue;
955966 },
......@@ -961,18 +972,6 @@ fn analyzeBodyInner(
961972 // continue the loop.
962973 // We also know that they cannot be referenced later, so we avoid
963974 // putting them into the map.
964 .breakpoint => {
965 if (!block.is_comptime) {
966 _ = try block.addNoOp(.breakpoint);
967 }
968 i += 1;
969 continue;
970 },
971 .fence => {
972 try sema.zirFence(block, inst);
973 i += 1;
974 continue;
975 },
976975 .dbg_stmt => {
977976 try sema.zirDbgStmt(block, inst);
978977 i += 1;
......@@ -988,6 +987,18 @@ fn analyzeBodyInner(
988987 i += 1;
989988 continue;
990989 },
990 .dbg_block_begin => {
991 dbg_block_begins += 1;
992 try sema.zirDbgBlockBegin(block);
993 i += 1;
994 continue;
995 },
996 .dbg_block_end => {
997 dbg_block_begins -= 1;
998 try sema.zirDbgBlockEnd(block);
999 i += 1;
1000 continue;
1001 },
9911002 .ensure_err_payload_void => {
9921003 try sema.zirEnsureErrPayloadVoid(block, inst);
9931004 i += 1;
......@@ -1078,21 +1089,11 @@ fn analyzeBodyInner(
10781089 i += 1;
10791090 continue;
10801091 },
1081 .set_align_stack => {
1082 try sema.zirSetAlignStack(block, inst);
1083 i += 1;
1084 continue;
1085 },
10861092 .set_cold => {
10871093 try sema.zirSetCold(block, inst);
10881094 i += 1;
10891095 continue;
10901096 },
1091 .set_float_mode => {
1092 try sema.zirSetFloatMode(block, inst);
1093 i += 1;
1094 continue;
1095 },
10961097 .set_runtime_safety => {
10971098 try sema.zirSetRuntimeSafety(block, inst);
10981099 i += 1;
......@@ -2452,15 +2453,12 @@ fn zirErrorSetDecl(
24522453 return sema.analyzeDeclVal(block, src, new_decl_index);
24532454}
24542455
2455fn zirRetPtr(
2456 sema: *Sema,
2457 block: *Block,
2458 extended: Zir.Inst.Extended.InstData,
2459) CompileError!Air.Inst.Ref {
2456fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
24602457 const tracy = trace(@src());
24612458 defer tracy.end();
24622459
2463 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
2460 const inst_data = sema.code.instructions.items(.data)[inst].node;
2461 const src: LazySrcLoc = .{ .node_offset = inst_data };
24642462 try sema.requireFunctionBlock(block, src);
24652463
24662464 if (block.is_comptime) {
......@@ -2493,15 +2491,12 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
24932491 return sema.analyzeRef(block, inst_data.src(), operand);
24942492}
24952493
2496fn zirRetType(
2497 sema: *Sema,
2498 block: *Block,
2499 extended: Zir.Inst.Extended.InstData,
2500) CompileError!Air.Inst.Ref {
2494fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
25012495 const tracy = trace(@src());
25022496 defer tracy.end();
25032497
2504 const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
2498 const inst_data = sema.code.instructions.items(.data)[inst].node;
2499 const src: LazySrcLoc = .{ .node_offset = inst_data };
25052500 try sema.requireFunctionBlock(block, src);
25062501 return sema.addType(sema.fn_ret_ty);
25072502}
......@@ -3746,9 +3741,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
37463741 sema.fn_ret_ty.zigTypeTag() == .ErrorUnion)
37473742 {
37483743 if (Zir.refToIndex(extra.lhs)) |ptr_index| {
3749 if (zir_tags[ptr_index] == .extended and
3750 zir_datas[ptr_index].extended.opcode == .ret_ptr)
3751 {
3744 if (zir_tags[ptr_index] == .ret_ptr) {
37523745 try sema.addToInferredErrorSet(operand);
37533746 }
37543747 }
......@@ -4392,11 +4385,11 @@ pub fn analyzeExport(
43924385 errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);
43934386}
43944387
4395fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4396 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4397 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
4398 const src: LazySrcLoc = inst_data.src();
4399 const alignment = try sema.resolveAlign(block, operand_src, inst_data.operand);
4388fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
4389 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
4390 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
4391 const src: LazySrcLoc = .{ .node_offset = extra.node };
4392 const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
44004393 if (alignment > 256) {
44014394 return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
44024395 alignment,
......@@ -4433,10 +4426,10 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
44334426 func.is_cold = is_cold;
44344427}
44354428
4436fn zirSetFloatMode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4437 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4438 const src: LazySrcLoc = inst_data.src();
4439 const float_mode = try sema.resolveBuiltinEnum(block, src, inst_data.operand, "FloatMode");
4429fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
4430 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
4431 const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
4432 const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode");
44404433 switch (float_mode) {
44414434 .Strict => return,
44424435 .Optimized => {
......@@ -4451,12 +4444,12 @@ fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
44514444 block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand);
44524445}
44534446
4454fn zirFence(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
4447fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
44554448 if (block.is_comptime) return;
44564449
4457 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
4458 const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
4459 const order = try sema.resolveAtomicOrder(block, order_src, inst_data.operand);
4450 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
4451 const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
4452 const order = try sema.resolveAtomicOrder(block, order_src, extra.operand);
44604453
44614454 if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) {
44624455 return sema.fail(block, order_src, "atomic ordering must be Acquire or stricter", .{});
......@@ -12337,14 +12330,15 @@ fn addRuntimeBreak(sema: *Sema, child_block: *Block, break_data: BreakData) !voi
1233712330}
1233812331
1233912332fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
12340 const tracy = trace(@src());
12341 defer tracy.end();
12342
1234312333 const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable";
1234412334 const src = inst_data.src();
12335
12336 if (block.is_comptime or inst_data.force_comptime) {
12337 return sema.fail(block, src, "reached unreachable code", .{});
12338 }
1234512339 try sema.requireRuntimeBlock(block, src);
1234612340 // TODO Add compile error for @optimizeFor occurring too late in a scope.
12347 try block.addUnreachable(src, inst_data.safety);
12341 try block.addUnreachable(src, true);
1234812342 return always_noreturn;
1234912343}
1235012344
......@@ -14143,12 +14137,11 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1414314137 return block.addBitCast(type_res, operand_coerced);
1414414138}
1414514139
14146fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
14147 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
14148 const src = inst_data.src();
14149 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
14150 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
14151 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
14140fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
14141 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
14142 const src: LazySrcLoc = .{ .node_offset = extra.node };
14143 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
14144 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
1415214145 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
1415314146 const operand = sema.resolveInst(extra.rhs);
1415414147 const operand_ty = sema.typeOf(operand);
......@@ -16006,15 +15999,24 @@ fn zirAwait(
1600615999 sema: *Sema,
1600716000 block: *Block,
1600816001 inst: Zir.Inst.Index,
16009 is_nosuspend: bool,
1601016002) CompileError!Air.Inst.Ref {
1601116003 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
1601216004 const src = inst_data.src();
1601316005
16014 _ = is_nosuspend;
1601516006 return sema.fail(block, src, "TODO: Sema.zirAwait", .{});
1601616007}
1601716008
16009fn zirAwaitNosuspend(
16010 sema: *Sema,
16011 block: *Block,
16012 extended: Zir.Inst.Extended.InstData,
16013) CompileError!Air.Inst.Ref {
16014 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
16015 const src: LazySrcLoc = .{ .node_offset = extra.node };
16016
16017 return sema.fail(block, src, "TODO: Sema.zirAwaitNosuspend", .{});
16018}
16019
1601816020fn zirVarExtended(
1601916021 sema: *Sema,
1602016022 block: *Block,
......@@ -16097,37 +16099,33 @@ fn zirVarExtended(
1609716099 return result;
1609816100}
1609916101
16100fn zirFuncExtended(
16101 sema: *Sema,
16102 block: *Block,
16103 extended: Zir.Inst.Extended.InstData,
16104 inst: Zir.Inst.Index,
16105) CompileError!Air.Inst.Ref {
16102fn zirFuncExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1610616103 const tracy = trace(@src());
1610716104 defer tracy.end();
1610816105
16109 const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand);
16110 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
16111 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node };
16106 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
16107 const src = inst_data.src();
16108 const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
16109
16110 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node };
1611216111 const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align
16113 const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
1611416112
1611516113 var extra_index: usize = extra.end;
1611616114
16117 const lib_name: ?[]const u8 = if (small.has_lib_name) blk: {
16115 const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: {
1611816116 const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
1611916117 extra_index += 1;
1612016118 break :blk lib_name;
1612116119 } else null;
1612216120
16123 const cc: std.builtin.CallingConvention = if (small.has_cc) blk: {
16121 const cc: std.builtin.CallingConvention = if (extra.data.bits.has_cc) blk: {
1612416122 const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1612516123 extra_index += 1;
1612616124 const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref);
1612716125 break :blk cc_tv.val.toEnum(std.builtin.CallingConvention);
1612816126 } else .Unspecified;
1612916127
16130 const align_val: Value = if (small.has_align) blk: {
16128 const align_val: Value = if (extra.data.bits.has_align) blk: {
1613116129 const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
1613216130 extra_index += 1;
1613316131 const align_tv = try sema.resolveInstConst(block, align_src, align_ref);
......@@ -16144,13 +16142,13 @@ fn zirFuncExtended(
1614416142 src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
1614516143 }
1614616144
16147 const is_var_args = small.is_var_args;
16148 const is_inferred_error = small.is_inferred_error;
16149 const is_extern = small.is_extern;
16145 const is_var_args = extra.data.bits.is_var_args;
16146 const is_inferred_error = extra.data.bits.is_inferred_error;
16147 const is_extern = extra.data.bits.is_extern;
1615016148
1615116149 return sema.funcCommon(
1615216150 block,
16153 extra.data.src_node,
16151 inst_data.src_node,
1615416152 inst,
1615516153 ret_ty_body,
1615616154 cc,
src/Zir.zig+75-79
......@@ -73,6 +73,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en
7373 i32 => @bitCast(i32, code.extra[i]),
7474 Inst.Call.Flags => @bitCast(Inst.Call.Flags, code.extra[i]),
7575 Inst.SwitchBlock.Bits => @bitCast(Inst.SwitchBlock.Bits, code.extra[i]),
76 Inst.ExtendedFunc.Bits => @bitCast(Inst.ExtendedFunc.Bits, code.extra[i]),
7677 else => @compileError("bad field type"),
7778 };
7879 i += 1;
......@@ -278,8 +279,6 @@ pub const Inst = struct {
278279 /// break instruction in a block, and the target block is the parent.
279280 /// Uses the `break` union field.
280281 break_inline,
281 /// Uses the `node` union field.
282 breakpoint,
283282 /// Function call.
284283 /// Uses `pl_node`. AST node is the function call. Payload is `Call`.
285284 call,
......@@ -331,6 +330,10 @@ pub const Inst = struct {
331330 /// Same as `dbg_var_ptr` but the local is always a const and the operand
332331 /// is the local's value.
333332 dbg_var_val,
333 /// Marks the beginning of a semantic scope for debug info variables.
334 dbg_block_begin,
335 /// Marks the end of a semantic scope for debug info variables.
336 dbg_block_end,
334337 /// Uses a name to identify a Decl and takes a pointer to it.
335338 /// Uses the `str_tok` union field.
336339 decl_ref,
......@@ -413,6 +416,10 @@ pub const Inst = struct {
413416 func,
414417 /// Same as `func` but has an inferred error set.
415418 func_inferred,
419 /// Represents a function declaration or function prototype, depending on
420 /// whether body_len is 0.
421 /// Uses the `pl_node` union field. `payload_index` points to a `ExtendedFunc`.
422 func_extended,
416423 /// Implements the `@import` builtin.
417424 /// Uses the `str_tok` field.
418425 import,
......@@ -499,6 +506,12 @@ pub const Inst = struct {
499506 /// this instruction; a following 'ret' instruction will do the diversion.
500507 /// Uses the `str_tok` union field.
501508 ret_err_value_code,
509 /// Obtains a pointer to the return value.
510 /// Uses the `node` union field.
511 ret_ptr,
512 /// Obtains the return type of the in-scope function.
513 /// Uses the `node` union field.
514 ret_type,
502515 /// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.
503516 /// Uses the `ptr_type_simple` union field.
504517 ptr_type_simple,
......@@ -744,8 +757,6 @@ pub const Inst = struct {
744757 size_of,
745758 /// Implements the `@bitSizeOf` builtin. Uses `un_node`.
746759 bit_size_of,
747 /// Implements the `@fence` builtin. Uses `un_node`.
748 fence,
749760
750761 /// Implement builtin `@ptrToInt`. Uses `un_node`.
751762 /// Convert a pointer to a `usize` integer.
......@@ -774,12 +785,8 @@ pub const Inst = struct {
774785 error_name,
775786 /// Implement builtin `@panic`. Uses `un_node`.
776787 panic,
777 /// Implement builtin `@setAlignStack`. Uses `un_node`.
778 set_align_stack,
779788 /// Implement builtin `@setCold`. Uses `un_node`.
780789 set_cold,
781 /// Implement builtin `@setFloatMode`. Uses `un_node`.
782 set_float_mode,
783790 /// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
784791 set_runtime_safety,
785792 /// Implement builtin `@sqrt`. Uses `un_node`.
......@@ -843,9 +850,6 @@ pub const Inst = struct {
843850 /// Convert an integer value to another integer type, asserting that the destination type
844851 /// can hold the same mathematical value.
845852 int_cast,
846 /// Implements the `@errSetCast` builtin.
847 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
848 err_set_cast,
849853 /// Implements the `@ptrCast` builtin.
850854 /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
851855 ptr_cast,
......@@ -972,7 +976,6 @@ pub const Inst = struct {
972976 /// Implements `resume` syntax. Uses `un_node` field.
973977 @"resume",
974978 @"await",
975 await_nosuspend,
976979
977980 /// When a type or function refers to a comptime value from an outer
978981 /// scope, that forms a closure over comptime value. The outer scope
......@@ -1028,8 +1031,6 @@ pub const Inst = struct {
10281031 .bool_br_and,
10291032 .bool_br_or,
10301033 .bool_not,
1031 .breakpoint,
1032 .fence,
10331034 .call,
10341035 .cmp_lt,
10351036 .cmp_lte,
......@@ -1044,6 +1045,8 @@ pub const Inst = struct {
10441045 .dbg_stmt,
10451046 .dbg_var_ptr,
10461047 .dbg_var_val,
1048 .dbg_block_begin,
1049 .dbg_block_end,
10471050 .decl_ref,
10481051 .decl_val,
10491052 .load,
......@@ -1064,6 +1067,7 @@ pub const Inst = struct {
10641067 .field_val_named,
10651068 .func,
10661069 .func_inferred,
1070 .func_extended,
10671071 .has_decl,
10681072 .int,
10691073 .int_big,
......@@ -1164,9 +1168,7 @@ pub const Inst = struct {
11641168 .bool_to_int,
11651169 .embed_file,
11661170 .error_name,
1167 .set_align_stack,
11681171 .set_cold,
1169 .set_float_mode,
11701172 .set_runtime_safety,
11711173 .sqrt,
11721174 .sin,
......@@ -1192,7 +1194,6 @@ pub const Inst = struct {
11921194 .int_to_ptr,
11931195 .float_cast,
11941196 .int_cast,
1195 .err_set_cast,
11961197 .ptr_cast,
11971198 .truncate,
11981199 .align_cast,
......@@ -1231,11 +1232,12 @@ pub const Inst = struct {
12311232 .c_import,
12321233 .@"resume",
12331234 .@"await",
1234 .await_nosuspend,
12351235 .ret_err_value_code,
12361236 .extended,
12371237 .closure_get,
12381238 .closure_capture,
1239 .ret_ptr,
1240 .ret_type,
12391241 => false,
12401242
12411243 .@"break",
......@@ -1258,13 +1260,13 @@ pub const Inst = struct {
12581260 /// AstGen uses this to find out if `Ref.void_value` should be used in place
12591261 /// of the result of a given instruction. This allows Sema to forego adding
12601262 /// the instruction to the map after analysis.
1261 pub fn isAlwaysVoid(tag: Tag) bool {
1263 pub fn isAlwaysVoid(tag: Tag, data: Data) bool {
12621264 return switch (tag) {
1263 .breakpoint,
1264 .fence,
12651265 .dbg_stmt,
12661266 .dbg_var_ptr,
12671267 .dbg_var_val,
1268 .dbg_block_begin,
1269 .dbg_block_end,
12681270 .ensure_result_used,
12691271 .ensure_result_non_error,
12701272 .ensure_err_payload_void,
......@@ -1283,9 +1285,7 @@ pub const Inst = struct {
12831285 .validate_array_init_comptime,
12841286 .@"export",
12851287 .export_value,
1286 .set_align_stack,
12871288 .set_cold,
1288 .set_float_mode,
12891289 .set_runtime_safety,
12901290 .memcpy,
12911291 .memset,
......@@ -1353,6 +1353,7 @@ pub const Inst = struct {
13531353 .field_val_named,
13541354 .func,
13551355 .func_inferred,
1356 .func_extended,
13561357 .has_decl,
13571358 .int,
13581359 .int_big,
......@@ -1464,7 +1465,6 @@ pub const Inst = struct {
14641465 .int_to_ptr,
14651466 .float_cast,
14661467 .int_cast,
1467 .err_set_cast,
14681468 .ptr_cast,
14691469 .truncate,
14701470 .align_cast,
......@@ -1500,9 +1500,7 @@ pub const Inst = struct {
15001500 .c_import,
15011501 .@"resume",
15021502 .@"await",
1503 .await_nosuspend,
15041503 .ret_err_value_code,
1505 .extended,
15061504 .closure_get,
15071505 .closure_capture,
15081506 .@"break",
......@@ -1514,11 +1512,18 @@ pub const Inst = struct {
15141512 .ret_load,
15151513 .ret_tok,
15161514 .ret_err_value,
1515 .ret_ptr,
1516 .ret_type,
15171517 .@"unreachable",
15181518 .repeat,
15191519 .repeat_inline,
15201520 .panic,
15211521 => false,
1522
1523 .extended => switch (data.extended.opcode) {
1524 .breakpoint, .fence => true,
1525 else => false,
1526 },
15221527 };
15231528 }
15241529
......@@ -1563,7 +1568,6 @@ pub const Inst = struct {
15631568 .bool_br_or = .bool_br,
15641569 .@"break" = .@"break",
15651570 .break_inline = .@"break",
1566 .breakpoint = .node,
15671571 .call = .pl_node,
15681572 .cmp_lt = .pl_node,
15691573 .cmp_lte = .pl_node,
......@@ -1580,6 +1584,8 @@ pub const Inst = struct {
15801584 .dbg_stmt = .dbg_stmt,
15811585 .dbg_var_ptr = .str_op,
15821586 .dbg_var_val = .str_op,
1587 .dbg_block_begin = .tok,
1588 .dbg_block_end = .tok,
15831589 .decl_ref = .str_tok,
15841590 .decl_val = .str_tok,
15851591 .load = .un_node,
......@@ -1602,6 +1608,7 @@ pub const Inst = struct {
16021608 .field_call_bind = .pl_node,
16031609 .func = .pl_node,
16041610 .func_inferred = .pl_node,
1611 .func_extended = .pl_node,
16051612 .import = .str_tok,
16061613 .int = .int,
16071614 .int_big = .str,
......@@ -1623,6 +1630,8 @@ pub const Inst = struct {
16231630 .ret_tok = .un_tok,
16241631 .ret_err_value = .str_tok,
16251632 .ret_err_value_code = .str_tok,
1633 .ret_ptr = .node,
1634 .ret_type = .node,
16261635 .ptr_type_simple = .ptr_type_simple,
16271636 .ptr_type = .ptr_type,
16281637 .slice_start = .pl_node,
......@@ -1685,7 +1694,6 @@ pub const Inst = struct {
16851694 .type_info = .un_node,
16861695 .size_of = .un_node,
16871696 .bit_size_of = .un_node,
1688 .fence = .un_node,
16891697
16901698 .ptr_to_int = .un_node,
16911699 .error_to_int = .un_node,
......@@ -1698,9 +1706,7 @@ pub const Inst = struct {
16981706 .embed_file = .un_node,
16991707 .error_name = .un_node,
17001708 .panic = .un_node,
1701 .set_align_stack = .un_node,
17021709 .set_cold = .un_node,
1703 .set_float_mode = .un_node,
17041710 .set_runtime_safety = .un_node,
17051711 .sqrt = .un_node,
17061712 .sin = .un_node,
......@@ -1728,7 +1734,6 @@ pub const Inst = struct {
17281734 .int_to_enum = .pl_node,
17291735 .float_cast = .pl_node,
17301736 .int_cast = .pl_node,
1731 .err_set_cast = .pl_node,
17321737 .ptr_cast = .pl_node,
17331738 .truncate = .pl_node,
17341739 .align_cast = .pl_node,
......@@ -1788,7 +1793,6 @@ pub const Inst = struct {
17881793
17891794 .@"resume" = .un_node,
17901795 .@"await" = .un_node,
1791 .await_nosuspend = .un_node,
17921796
17931797 .closure_capture = .un_tok,
17941798 .closure_get = .inst_node,
......@@ -1806,11 +1810,6 @@ pub const Inst = struct {
18061810 /// Rarer instructions are here; ones that do not fit in the 8-bit `Tag` enum.
18071811 /// `noreturn` instructions may not go here; they must be part of the main `Tag` enum.
18081812 pub const Extended = enum(u16) {
1809 /// Represents a function declaration or function prototype, depending on
1810 /// whether body_len is 0.
1811 /// `operand` is payload index to `ExtendedFunc`.
1812 /// `small` is `ExtendedFunc.Small`.
1813 func,
18141813 /// Declares a global variable.
18151814 /// `operand` is payload index to `ExtendedVar`.
18161815 /// `small` is `ExtendedVar.Small`.
......@@ -1834,12 +1833,6 @@ pub const Inst = struct {
18341833 /// `operand` is payload index to `OpaqueDecl`.
18351834 /// `small` is `OpaqueDecl.Small`.
18361835 opaque_decl,
1837 /// Obtains a pointer to the return value.
1838 /// `operand` is `src_node: i32`.
1839 ret_ptr,
1840 /// Obtains the return type of the in-scope function.
1841 /// `operand` is `src_node: i32`.
1842 ret_type,
18431836 /// Implements the `@This` builtin.
18441837 /// `operand` is `src_node: i32`.
18451838 this,
......@@ -1917,10 +1910,6 @@ pub const Inst = struct {
19171910 /// The `@prefetch` builtin.
19181911 /// `operand` is payload index to `BinNode`.
19191912 prefetch,
1920 /// Marks the beginning of a semantic scope for debug info variables.
1921 dbg_block_begin,
1922 /// Marks the end of a semantic scope for debug info variables.
1923 dbg_block_end,
19241913 /// Given a pointer to a struct or object that contains virtual fields, returns the
19251914 /// named field. If there is no named field, searches in the type for a decl that
19261915 /// matches the field name. The decl is resolved and we ensure that it's a function
......@@ -1931,6 +1920,22 @@ pub const Inst = struct {
19311920 /// `builtin_call` instruction. Any other use is invalid zir and may crash the compiler.
19321921 /// Uses `pl_node` field. The AST node is the `@field` builtin. Payload is FieldNamedNode.
19331922 field_call_bind_named,
1923 /// Implements the `@fence` builtin.
1924 /// `operand` is payload index to `UnNode`.
1925 fence,
1926 /// Implement builtin `@setFloatMode`.
1927 /// `operand` is payload index to `UnNode`.
1928 set_float_mode,
1929 /// Implement builtin `@setAlignStack`.
1930 /// `operand` is payload index to `UnNode`.
1931 set_align_stack,
1932 /// Implements the `@errSetCast` builtin.
1933 /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
1934 err_set_cast,
1935 /// `operand` is payload index to `UnNode`.
1936 await_nosuspend,
1937 /// `operand` is `src_node: i32`.
1938 breakpoint,
19341939
19351940 pub const InstData = struct {
19361941 opcode: Extended,
......@@ -2502,11 +2507,7 @@ pub const Inst = struct {
25022507 /// Offset from Decl AST node index.
25032508 /// `Tag` determines which kind of AST node this points to.
25042509 src_node: i32,
2505 /// `false`: Not safety checked - the compiler will assume the
2506 /// correctness of this instruction.
2507 /// `true`: In safety-checked modes, this will generate a call
2508 /// to the panic function unless it can be proven unreachable by the compiler.
2509 safety: bool,
2510 force_comptime: bool,
25102511
25112512 pub fn src(self: @This()) LazySrcLoc {
25122513 return .{ .node_offset = self.src_node };
......@@ -2623,14 +2624,14 @@ pub const Inst = struct {
26232624 /// 4. body: Index // for each body_len
26242625 /// 5. src_locs: Func.SrcLocs // if body_len != 0
26252626 pub const ExtendedFunc = struct {
2626 src_node: i32,
26272627 /// If this is 0 it means a void return type.
26282628 ret_body_len: u32,
26292629 /// Points to the block that contains the param instructions for this function.
26302630 param_block: Index,
26312631 body_len: u32,
2632 bits: Bits,
26322633
2633 pub const Small = packed struct {
2634 pub const Bits = packed struct {
26342635 is_var_args: bool,
26352636 is_inferred_error: bool,
26362637 has_lib_name: bool,
......@@ -2638,7 +2639,7 @@ pub const Inst = struct {
26382639 has_align: bool,
26392640 is_test: bool,
26402641 is_extern: bool,
2641 _: u9 = undefined,
2642 _: u25 = undefined,
26422643 };
26432644 };
26442645
......@@ -3462,14 +3463,11 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator {
34623463 switch (tags[decl_inst]) {
34633464 // Functions are allowed and yield no iterations.
34643465 // There is one case matching this in the extended instruction set below.
3465 .func,
3466 .func_inferred,
3467 => return declIteratorInner(zir, 0, 0),
3466 .func, .func_inferred, .func_extended => return declIteratorInner(zir, 0, 0),
34683467
34693468 .extended => {
34703469 const extended = datas[decl_inst].extended;
34713470 switch (extended.opcode) {
3472 .func => return declIteratorInner(zir, 0, 0),
34733471 .struct_decl => {
34743472 const small = @bitCast(Inst.StructDecl.Small, extended.small);
34753473 var extra_index: usize = extended.operand;
......@@ -3574,21 +3572,21 @@ fn findDeclsInner(
35743572 const body = zir.extra[extra.end..][0..extra.data.body_len];
35753573 return zir.findDeclsBody(list, body);
35763574 },
3575 .func_extended => {
3576 try list.append(inst);
3577
3578 const inst_data = datas[inst].pl_node;
3579 const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index);
3580 var extra_index: usize = extra.end;
3581 extra_index += @boolToInt(extra.data.bits.has_lib_name);
3582 extra_index += @boolToInt(extra.data.bits.has_cc);
3583 extra_index += @boolToInt(extra.data.bits.has_align);
3584 const body = zir.extra[extra_index..][0..extra.data.body_len];
3585 return zir.findDeclsBody(list, body);
3586 },
35773587 .extended => {
35783588 const extended = datas[inst].extended;
35793589 switch (extended.opcode) {
3580 .func => {
3581 try list.append(inst);
3582
3583 const extra = zir.extraData(Inst.ExtendedFunc, extended.operand);
3584 const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
3585 var extra_index: usize = extra.end;
3586 extra_index += @boolToInt(small.has_lib_name);
3587 extra_index += @boolToInt(small.has_cc);
3588 extra_index += @boolToInt(small.has_align);
3589 const body = zir.extra[extra_index..][0..extra.data.body_len];
3590 return zir.findDeclsBody(list, body);
3591 },
35923590
35933591 // Decl instructions are interesting but have no body.
35943592 // TODO yes they do have a body actually. recurse over them just like block instructions.
......@@ -3735,15 +3733,13 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
37353733 .body = body,
37363734 };
37373735 },
3738 .extended => blk: {
3739 const extended = datas[fn_inst].extended;
3740 assert(extended.opcode == .func);
3741 const extra = zir.extraData(Inst.ExtendedFunc, extended.operand);
3742 const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
3736 .func_extended => blk: {
3737 const inst_data = datas[fn_inst].pl_node;
3738 const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index);
37433739 var extra_index: usize = extra.end;
3744 extra_index += @boolToInt(small.has_lib_name);
3745 extra_index += @boolToInt(small.has_cc);
3746 extra_index += @boolToInt(small.has_align);
3740 extra_index += @boolToInt(extra.data.bits.has_lib_name);
3741 extra_index += @boolToInt(extra.data.bits.has_cc);
3742 extra_index += @boolToInt(extra.data.bits.has_align);
37473743 const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len];
37483744 extra_index += ret_ty_body.len;
37493745 const body = zir.extra[extra_index..][0..extra.data.body_len];
src/print_zir.zig+33-28
......@@ -200,9 +200,7 @@ const Writer = struct {
200200 .embed_file,
201201 .error_name,
202202 .panic,
203 .set_align_stack,
204203 .set_cold,
205 .set_float_mode,
206204 .set_runtime_safety,
207205 .sqrt,
208206 .sin,
......@@ -231,8 +229,6 @@ const Writer = struct {
231229 .elem_type,
232230 .@"resume",
233231 .@"await",
234 .await_nosuspend,
235 .fence,
236232 .switch_cond,
237233 .switch_cond_ref,
238234 .array_base_ptr,
......@@ -343,7 +339,6 @@ const Writer = struct {
343339 .int_to_enum,
344340 .float_cast,
345341 .int_cast,
346 .err_set_cast,
347342 .ptr_cast,
348343 .truncate,
349344 .align_cast,
......@@ -405,13 +400,14 @@ const Writer = struct {
405400
406401 .as_node => try self.writeAs(stream, inst),
407402
408 .breakpoint,
409403 .repeat,
410404 .repeat_inline,
411405 .alloc_inferred,
412406 .alloc_inferred_mut,
413407 .alloc_inferred_comptime,
414408 .alloc_inferred_comptime_mut,
409 .ret_ptr,
410 .ret_type,
415411 => try self.writeNode(stream, inst),
416412
417413 .error_value,
......@@ -433,6 +429,7 @@ const Writer = struct {
433429
434430 .func => try self.writeFunc(stream, inst, false),
435431 .func_inferred => try self.writeFunc(stream, inst, true),
432 .func_extended => try self.writeFuncExtended(stream, inst),
436433
437434 .@"unreachable" => try self.writeUnreachable(stream, inst),
438435
......@@ -444,6 +441,10 @@ const Writer = struct {
444441
445442 .dbg_stmt => try self.writeDbgStmt(stream, inst),
446443
444 .dbg_block_begin,
445 .dbg_block_end,
446 => try stream.writeAll("))"),
447
447448 .closure_get => try self.writeInstNode(stream, inst),
448449
449450 .extended => try self.writeExtended(stream, inst),
......@@ -454,13 +455,12 @@ const Writer = struct {
454455 const extended = self.code.instructions.items(.data)[inst].extended;
455456 try stream.print("{s}(", .{@tagName(extended.opcode)});
456457 switch (extended.opcode) {
457 .ret_ptr,
458 .ret_type,
459458 .this,
460459 .ret_addr,
461460 .error_return_trace,
462461 .frame,
463462 .frame_address,
463 .breakpoint,
464464 => try self.writeExtNode(stream, extended),
465465
466466 .builtin_src => {
......@@ -469,12 +469,7 @@ const Writer = struct {
469469 try stream.print(":{d}:{d}", .{ inst_data.line + 1, inst_data.column + 1 });
470470 },
471471
472 .dbg_block_begin,
473 .dbg_block_end,
474 => try stream.writeAll("))"),
475
476472 .@"asm" => try self.writeAsm(stream, extended),
477 .func => try self.writeFuncExtended(stream, extended),
478473 .variable => try self.writeVarExtended(stream, extended),
479474 .alloc => try self.writeAllocExtended(stream, extended),
480475
......@@ -492,7 +487,14 @@ const Writer = struct {
492487 .enum_decl => try self.writeEnumDecl(stream, extended),
493488 .opaque_decl => try self.writeOpaqueDecl(stream, extended),
494489
495 .c_undef, .c_include, .wasm_memory_size => {
490 .await_nosuspend,
491 .c_undef,
492 .c_include,
493 .fence,
494 .set_float_mode,
495 .set_align_stack,
496 .wasm_memory_size,
497 => {
496498 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
497499 const src: LazySrcLoc = .{ .node_offset = inst_data.node };
498500 try self.writeInstRef(stream, inst_data.operand);
......@@ -500,7 +502,12 @@ const Writer = struct {
500502 try self.writeSrc(stream, src);
501503 },
502504
503 .builtin_extern, .c_define, .wasm_memory_grow, .prefetch => {
505 .builtin_extern,
506 .c_define,
507 .err_set_cast,
508 .wasm_memory_grow,
509 .prefetch,
510 => {
504511 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
505512 const src: LazySrcLoc = .{ .node_offset = inst_data.node };
506513 try self.writeInstRef(stream, inst_data.lhs);
......@@ -1913,24 +1920,24 @@ const Writer = struct {
19131920 );
19141921 }
19151922
1916 fn writeFuncExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
1917 const extra = self.code.extraData(Zir.Inst.ExtendedFunc, extended.operand);
1918 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
1919 const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
1923 fn writeFuncExtended(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
1924 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
1925 const extra = self.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
1926 const src = inst_data.src();
19201927
19211928 var extra_index: usize = extra.end;
1922 if (small.has_lib_name) {
1929 if (extra.data.bits.has_lib_name) {
19231930 const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
19241931 extra_index += 1;
19251932 try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)});
19261933 }
1927 try self.writeFlag(stream, "test, ", small.is_test);
1928 const cc: Zir.Inst.Ref = if (!small.has_cc) .none else blk: {
1934 try self.writeFlag(stream, "test, ", extra.data.bits.is_test);
1935 const cc: Zir.Inst.Ref = if (!extra.data.bits.has_cc) .none else blk: {
19291936 const cc = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
19301937 extra_index += 1;
19311938 break :blk cc;
19321939 };
1933 const align_inst: Zir.Inst.Ref = if (!small.has_align) .none else blk: {
1940 const align_inst: Zir.Inst.Ref = if (!extra.data.bits.has_align) .none else blk: {
19341941 const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
19351942 extra_index += 1;
19361943 break :blk align_inst;
......@@ -1949,9 +1956,9 @@ const Writer = struct {
19491956 return self.writeFuncCommon(
19501957 stream,
19511958 ret_ty_body,
1952 small.is_inferred_error,
1953 small.is_var_args,
1954 small.is_extern,
1959 extra.data.bits.is_inferred_error,
1960 extra.data.bits.is_var_args,
1961 extra.data.bits.is_extern,
19551962 cc,
19561963 align_inst,
19571964 body,
......@@ -2091,8 +2098,6 @@ const Writer = struct {
20912098
20922099 fn writeUnreachable(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
20932100 const inst_data = self.code.instructions.items(.data)[inst].@"unreachable";
2094 const safety_str = if (inst_data.safety) "safe" else "unsafe";
2095 try stream.print("{s}) ", .{safety_str});
20962101 try self.writeSrc(stream, inst_data.src());
20972102 }
20982103
test/compile_errors/stage2/comptime_unreachable.zig created+7
......@@ -0,0 +1,7 @@
1pub export fn entry() void {
2 comptime unreachable;
3}
4
5// error
6//
7// :2:14: error: reached unreachable code
test/incremental/x86_64-linux/comptime_var.3.zig+1-1
......@@ -7,4 +7,4 @@ pub fn main() void {}
77
88// error
99//
10// :4:17: error: unable to resolve comptime value
10// :4:17: error: reached unreachable code
test/incremental/x86_64-macos/comptime_var.3.zig+1-1
......@@ -7,4 +7,4 @@ pub fn main() void {}
77
88// error
99//
10// :4:17: error: unable to resolve comptime value
10// :4:17: error: reached unreachable code