aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-04-29 22:50:53 -0400
committerGitHub <noreply@github.com>2022-04-29 22:50:53 -0400
commitcc39d453c45645296cd771c94d97b8a77469be91 (patch)
tree8d9c857255ac15fe2f8125789f8a42a7a03573eb /src
parenta0a2ce92ca129d28e22c63f7bace1672c43776b5 (diff)
parent596f7df02e78adf334eed4a1f14eafa31ca611b9 (diff)
downloadzig-cc39d453c45645296cd771c94d97b8a77469be91.tar.gz
zig-cc39d453c45645296cd771c94d97b8a77469be91.zip
Merge pull request #11549 from Vexu/stage2-fixes
Stage2: fix comptime unreachable, adjust Zir.Extended
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig114
-rw-r--r--src/Module.zig8
-rw-r--r--src/Sema.zig180
-rw-r--r--src/Zir.zig154
-rw-r--r--src/print_zir.zig61
5 files changed, 274 insertions, 243 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index c9fd82bd5f..f74a2b2d39 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -72,6 +72,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void {
i32 => @bitCast(u32, @field(extra, field.name)),
Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)),
Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)),
+ Zir.Inst.ExtendedFunc.Bits => @bitCast(u32, @field(extra, field.name)),
else => @compileError("bad field type"),
};
i += 1;
@@ -740,7 +741,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr
_ = try gz.addAsIndex(.{
.tag = .@"unreachable",
.data = .{ .@"unreachable" = .{
- .safety = true,
+ .force_comptime = gz.force_comptime,
.src_node = gz.nodeIndexToRelative(node),
} },
});
@@ -1078,8 +1079,14 @@ fn awaitExpr(
});
}
const operand = try expr(gz, scope, .none, rhs_node);
- const tag: Zir.Inst.Tag = if (gz.nosuspend_node != 0) .await_nosuspend else .@"await";
- const result = try gz.addUnNode(tag, operand, node);
+ const result = if (gz.nosuspend_node != 0)
+ try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{
+ .node = gz.nodeIndexToRelative(node),
+ .operand = operand,
+ })
+ else
+ try gz.addUnNode(.@"await", operand, node);
+
return rvalue(gz, rl, result, node);
}
@@ -2239,6 +2246,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.field_val_named,
.func,
.func_inferred,
+ .func_extended,
.int,
.int_big,
.float,
@@ -2349,7 +2357,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.int_to_ptr,
.float_cast,
.int_cast,
- .err_set_cast,
.ptr_cast,
.truncate,
.align_cast,
@@ -2386,15 +2393,24 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.c_import,
.@"resume",
.@"await",
- .await_nosuspend,
.ret_err_value_code,
- .extended,
.closure_get,
.array_base_ptr,
.field_base_ptr,
.param_type,
+ .ret_ptr,
+ .ret_type,
=> break :b false,
+ .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {
+ .breakpoint,
+ .fence,
+ .set_align_stack,
+ .set_float_mode,
+ => break :b true,
+ else => break :b false,
+ },
+
// ZIR instructions that are always `noreturn`.
.@"break",
.break_inline,
@@ -2415,11 +2431,11 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
},
// ZIR instructions that are always `void`.
- .breakpoint,
- .fence,
.dbg_stmt,
.dbg_var_ptr,
.dbg_var_val,
+ .dbg_block_begin,
+ .dbg_block_end,
.ensure_result_used,
.ensure_result_non_error,
.@"export",
@@ -2436,9 +2452,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.validate_struct_init_comptime,
.validate_array_init,
.validate_array_init_comptime,
- .set_align_stack,
.set_cold,
- .set_float_mode,
.set_runtime_safety,
.closure_capture,
.memcpy,
@@ -6310,9 +6324,9 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
}
const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{
- .ptr = try gz.addNodeExtended(.ret_ptr, node),
+ .ptr = try gz.addNode(.ret_ptr, node),
} else .{
- .ty = try gz.addNodeExtended(.ret_type, node),
+ .ty = try gz.addNode(.ret_type, node),
};
const prev_anon_name_strategy = gz.anon_name_strategy;
gz.anon_name_strategy = .func;
@@ -7183,7 +7197,26 @@ fn builtinCall(
},
.fence => {
const order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[0]);
- const result = try gz.addUnNode(.fence, order, node);
+ const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{
+ .node = gz.nodeIndexToRelative(node),
+ .operand = order,
+ });
+ return rvalue(gz, rl, result, node);
+ },
+ .set_float_mode => {
+ const order = try expr(gz, scope, .{ .coerced_ty = .float_mode_type }, params[0]);
+ const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{
+ .node = gz.nodeIndexToRelative(node),
+ .operand = order,
+ });
+ return rvalue(gz, rl, result, node);
+ },
+ .set_align_stack => {
+ const order = try expr(gz, scope, align_rl, params[0]);
+ const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{
+ .node = gz.nodeIndexToRelative(node),
+ .operand = order,
+ });
return rvalue(gz, rl, result, node);
},
@@ -7198,14 +7231,13 @@ fn builtinCall(
return rvalue(gz, rl, result, node);
},
- .breakpoint => return simpleNoOpVoid(gz, rl, node, .breakpoint),
-
// zig fmt: off
.This => return rvalue(gz, rl, try gz.addNodeExtended(.this, node), node),
.return_address => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr, node), node),
.error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node),
.frame => return rvalue(gz, rl, try gz.addNodeExtended(.frame, node), node),
.frame_address => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address, node), node),
+ .breakpoint => return rvalue(gz, rl, try gz.addNodeExtended(.breakpoint, node), node),
.type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info),
.size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of),
@@ -7222,9 +7254,7 @@ fn builtinCall(
.embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file),
.error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name),
.panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .panic),
- .set_align_stack => return simpleUnOp(gz, scope, rl, node, align_rl, params[0], .set_align_stack),
.set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold),
- .set_float_mode => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .float_mode_type }, params[0], .set_float_mode),
.set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety),
.sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt),
.sin => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sin),
@@ -7252,7 +7282,6 @@ fn builtinCall(
.int_to_enum => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum),
.float_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast),
.int_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast),
- .err_set_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .err_set_cast),
.ptr_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast),
.truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate),
// zig fmt: on
@@ -7266,6 +7295,14 @@ fn builtinCall(
});
return rvalue(gz, rl, result, node);
},
+ .err_set_cast => {
+ const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{
+ .lhs = try typeExpr(gz, scope, params[0]),
+ .rhs = try expr(gz, scope, .none, params[1]),
+ .node = gz.nodeIndexToRelative(node),
+ });
+ return rvalue(gz, rl, result, node);
+ },
// zig fmt: off
.has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl),
@@ -8940,7 +8977,8 @@ fn rvalue(
const result = r: {
if (refToIndex(raw_result)) |result_index| {
const zir_tags = gz.astgen.instructions.items(.tag);
- if (zir_tags[result_index].isAlwaysVoid()) {
+ const data = gz.astgen.instructions.items(.data)[result_index];
+ if (zir_tags[result_index].isAlwaysVoid(data)) {
break :r Zir.Inst.Ref.void_value;
}
}
@@ -9987,10 +10025,18 @@ const GenZir = struct {
@boolToInt(args.cc != .none),
);
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{
- .src_node = gz.nodeIndexToRelative(args.src_node),
.param_block = args.param_block,
.ret_body_len = @intCast(u32, ret_ty.len),
.body_len = @intCast(u32, body.len),
+ .bits = .{
+ .is_var_args = args.is_var_args,
+ .is_inferred_error = args.is_inferred_error,
+ .has_lib_name = args.lib_name != 0,
+ .has_cc = args.cc != .none,
+ .has_align = args.align_inst != .none,
+ .is_test = args.is_test,
+ .is_extern = args.is_extern,
+ },
});
if (args.lib_name != 0) {
astgen.extra.appendAssumeCapacity(args.lib_name);
@@ -10014,19 +10060,10 @@ const GenZir = struct {
astgen.instructions.items(.data)[args.ret_br].@"break".block_inst = new_index;
}
astgen.instructions.appendAssumeCapacity(.{
- .tag = .extended,
- .data = .{ .extended = .{
- .opcode = .func,
- .small = @bitCast(u16, Zir.Inst.ExtendedFunc.Small{
- .is_var_args = args.is_var_args,
- .is_inferred_error = args.is_inferred_error,
- .has_lib_name = args.lib_name != 0,
- .has_cc = args.cc != .none,
- .has_align = args.align_inst != .none,
- .is_test = args.is_test,
- .is_extern = args.is_extern,
- }),
- .operand = payload_index,
+ .tag = .func_extended,
+ .data = .{ .pl_node = .{
+ .src_node = gz.nodeIndexToRelative(args.src_node),
+ .payload_index = payload_index,
} },
});
gz.instructions.appendAssumeCapacity(new_index);
@@ -10893,9 +10930,7 @@ const GenZir = struct {
fn addDbgBlockBegin(gz: *GenZir) !void {
if (gz.force_comptime) return;
- _ = try gz.add(.{ .tag = .extended, .data = .{
- .extended = .{ .opcode = .dbg_block_begin, .small = undefined, .operand = undefined },
- } });
+ _ = try gz.add(.{ .tag = .dbg_block_begin, .data = undefined });
}
fn addDbgBlockEnd(gz: *GenZir) !void {
@@ -10903,18 +10938,15 @@ const GenZir = struct {
const gpa = gz.astgen.gpa;
const tags = gz.astgen.instructions.items(.tag);
- const data = gz.astgen.instructions.items(.data);
const last_inst = gz.instructions.items[gz.instructions.items.len - 1];
// remove dbg_block_begin immediately followed by dbg_block_end
- if (tags[last_inst] == .extended and data[last_inst].extended.opcode == .dbg_block_begin) {
+ if (tags[last_inst] == .dbg_block_begin) {
_ = gz.instructions.pop();
return;
}
const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len);
- try gz.astgen.instructions.append(gpa, .{ .tag = .extended, .data = .{
- .extended = .{ .opcode = .dbg_block_end, .small = undefined, .operand = undefined },
- } });
+ try gz.astgen.instructions.append(gpa, .{ .tag = .dbg_block_end, .data = undefined });
try gz.instructions.insert(gpa, gz.instructions.items.len - 1, new_index);
}
diff --git a/src/Module.zig b/src/Module.zig
index 1119d73ab0..55ec1fdd2c 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1532,10 +1532,10 @@ pub const Fn = struct {
switch (zir_tags[func.zir_body_inst]) {
.func => return false,
.func_inferred => return true,
- .extended => {
- const extended = zir.instructions.items(.data)[func.zir_body_inst].extended;
- const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
- return small.is_inferred_error;
+ .func_extended => {
+ const inst_data = zir.instructions.items(.data)[func.zir_body_inst].pl_node;
+ const extra = zir.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
+ return extra.data.bits.is_inferred_error;
},
else => unreachable,
}
diff --git a/src/Sema.zig b/src/Sema.zig
index c9d8f090ae..ccfb11e639 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -745,6 +745,7 @@ fn analyzeBodyInner(
.field_call_bind => try sema.zirFieldCallBind(block, inst),
.func => try sema.zirFunc(block, inst, false),
.func_inferred => try sema.zirFunc(block, inst, true),
+ .func_extended => try sema.zirFuncExtended(block, inst),
.import => try sema.zirImport(block, inst),
.indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst),
.int => try sema.zirInt(block, inst),
@@ -819,7 +820,6 @@ fn analyzeBodyInner(
.int_to_ptr => try sema.zirIntToPtr(block, inst),
.float_cast => try sema.zirFloatCast(block, inst),
.int_cast => try sema.zirIntCast(block, inst),
- .err_set_cast => try sema.zirErrSetCast(block, inst),
.ptr_cast => try sema.zirPtrCast(block, inst),
.truncate => try sema.zirTruncate(block, inst),
.align_cast => try sema.zirAlignCast(block, inst),
@@ -842,8 +842,7 @@ fn analyzeBodyInner(
.field_parent_ptr => try sema.zirFieldParentPtr(block, inst),
.builtin_async_call => try sema.zirBuiltinAsyncCall(block, inst),
.@"resume" => try sema.zirResume(block, inst),
- .@"await" => try sema.zirAwait(block, inst, false),
- .await_nosuspend => try sema.zirAwait(block, inst, true),
+ .@"await" => try sema.zirAwait(block, inst),
.array_base_ptr => try sema.zirArrayBasePtr(block, inst),
.field_base_ptr => try sema.zirFieldBasePtr(block, inst),
@@ -894,6 +893,9 @@ fn analyzeBodyInner(
.shl_exact => try sema.zirShl(block, inst, .shl_exact),
.shl_sat => try sema.zirShl(block, inst, .shl_sat),
+ .ret_ptr => try sema.zirRetPtr(block, inst),
+ .ret_type => try sema.zirRetType(block, inst),
+
// Instructions that we know to *always* be noreturn based solely on their tag.
// These functions match the return type of analyzeBody so that we can
// tail call them here.
@@ -910,14 +912,11 @@ fn analyzeBodyInner(
const extended = datas[inst].extended;
break :ext switch (extended.opcode) {
// zig fmt: off
- .func => try sema.zirFuncExtended( block, extended, inst),
.variable => try sema.zirVarExtended( block, extended),
.struct_decl => try sema.zirStructDecl( block, extended, inst),
.enum_decl => try sema.zirEnumDecl( block, extended),
.union_decl => try sema.zirUnionDecl( block, extended, inst),
.opaque_decl => try sema.zirOpaqueDecl( block, extended),
- .ret_ptr => try sema.zirRetPtr( block, extended),
- .ret_type => try sema.zirRetType( block, extended),
.this => try sema.zirThis( block, extended),
.ret_addr => try sema.zirRetAddr( block, extended),
.builtin_src => try sema.zirBuiltinSrc( block, extended),
@@ -940,16 +939,28 @@ fn analyzeBodyInner(
.wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended),
.prefetch => try sema.zirPrefetch( block, extended),
.field_call_bind_named => try sema.zirFieldCallBindNamed(block, extended),
+ .err_set_cast => try sema.zirErrSetCast( block, extended),
+ .await_nosuspend => try sema.zirAwaitNosuspend( block, extended),
// zig fmt: on
- .dbg_block_begin => {
- dbg_block_begins += 1;
- try sema.zirDbgBlockBegin(block);
+ .fence => {
+ try sema.zirFence(block, extended);
+ i += 1;
+ continue;
+ },
+ .set_float_mode => {
+ try sema.zirSetFloatMode(block, extended);
i += 1;
continue;
},
- .dbg_block_end => {
- dbg_block_begins -= 1;
- try sema.zirDbgBlockEnd(block);
+ .set_align_stack => {
+ try sema.zirSetAlignStack(block, extended);
+ i += 1;
+ continue;
+ },
+ .breakpoint => {
+ if (!block.is_comptime) {
+ _ = try block.addNoOp(.breakpoint);
+ }
i += 1;
continue;
},
@@ -961,18 +972,6 @@ fn analyzeBodyInner(
// continue the loop.
// We also know that they cannot be referenced later, so we avoid
// putting them into the map.
- .breakpoint => {
- if (!block.is_comptime) {
- _ = try block.addNoOp(.breakpoint);
- }
- i += 1;
- continue;
- },
- .fence => {
- try sema.zirFence(block, inst);
- i += 1;
- continue;
- },
.dbg_stmt => {
try sema.zirDbgStmt(block, inst);
i += 1;
@@ -988,6 +987,18 @@ fn analyzeBodyInner(
i += 1;
continue;
},
+ .dbg_block_begin => {
+ dbg_block_begins += 1;
+ try sema.zirDbgBlockBegin(block);
+ i += 1;
+ continue;
+ },
+ .dbg_block_end => {
+ dbg_block_begins -= 1;
+ try sema.zirDbgBlockEnd(block);
+ i += 1;
+ continue;
+ },
.ensure_err_payload_void => {
try sema.zirEnsureErrPayloadVoid(block, inst);
i += 1;
@@ -1078,21 +1089,11 @@ fn analyzeBodyInner(
i += 1;
continue;
},
- .set_align_stack => {
- try sema.zirSetAlignStack(block, inst);
- i += 1;
- continue;
- },
.set_cold => {
try sema.zirSetCold(block, inst);
i += 1;
continue;
},
- .set_float_mode => {
- try sema.zirSetFloatMode(block, inst);
- i += 1;
- continue;
- },
.set_runtime_safety => {
try sema.zirSetRuntimeSafety(block, inst);
i += 1;
@@ -2452,15 +2453,12 @@ fn zirErrorSetDecl(
return sema.analyzeDeclVal(block, src, new_decl_index);
}
-fn zirRetPtr(
- sema: *Sema,
- block: *Block,
- extended: Zir.Inst.Extended.InstData,
-) CompileError!Air.Inst.Ref {
+fn zirRetPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
- const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
+ const inst_data = sema.code.instructions.items(.data)[inst].node;
+ const src: LazySrcLoc = .{ .node_offset = inst_data };
try sema.requireFunctionBlock(block, src);
if (block.is_comptime) {
@@ -2493,15 +2491,12 @@ fn zirRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
return sema.analyzeRef(block, inst_data.src(), operand);
}
-fn zirRetType(
- sema: *Sema,
- block: *Block,
- extended: Zir.Inst.Extended.InstData,
-) CompileError!Air.Inst.Ref {
+fn zirRetType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
- const src: LazySrcLoc = .{ .node_offset = @bitCast(i32, extended.operand) };
+ const inst_data = sema.code.instructions.items(.data)[inst].node;
+ const src: LazySrcLoc = .{ .node_offset = inst_data };
try sema.requireFunctionBlock(block, src);
return sema.addType(sema.fn_ret_ty);
}
@@ -3746,9 +3741,7 @@ fn zirStoreNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!v
sema.fn_ret_ty.zigTypeTag() == .ErrorUnion)
{
if (Zir.refToIndex(extra.lhs)) |ptr_index| {
- if (zir_tags[ptr_index] == .extended and
- zir_datas[ptr_index].extended.opcode == .ret_ptr)
- {
+ if (zir_tags[ptr_index] == .ret_ptr) {
try sema.addToInferredErrorSet(operand);
}
}
@@ -4392,11 +4385,11 @@ pub fn analyzeExport(
errdefer de_gop.value_ptr.* = gpa.shrink(de_gop.value_ptr.*, de_gop.value_ptr.len - 1);
}
-fn zirSetAlignStack(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const src: LazySrcLoc = inst_data.src();
- const alignment = try sema.resolveAlign(block, operand_src, inst_data.operand);
+fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
+ const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+ const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ const alignment = try sema.resolveAlign(block, operand_src, extra.operand);
if (alignment > 256) {
return sema.fail(block, src, "attempt to @setAlignStack({d}); maximum is 256", .{
alignment,
@@ -4433,10 +4426,10 @@ fn zirSetCold(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
func.is_cold = is_cold;
}
-fn zirSetFloatMode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src: LazySrcLoc = inst_data.src();
- const float_mode = try sema.resolveBuiltinEnum(block, src, inst_data.operand, "FloatMode");
+fn zirSetFloatMode(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
+ const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+ const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const float_mode = try sema.resolveBuiltinEnum(block, src, extra.operand, "FloatMode");
switch (float_mode) {
.Strict => return,
.Optimized => {
@@ -4451,12 +4444,12 @@ fn zirSetRuntimeSafety(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile
block.want_safety = try sema.resolveConstBool(block, operand_src, inst_data.operand);
}
-fn zirFence(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
+fn zirFence(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!void {
if (block.is_comptime) return;
- const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const order = try sema.resolveAtomicOrder(block, order_src, inst_data.operand);
+ const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+ const order_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const order = try sema.resolveAtomicOrder(block, order_src, extra.operand);
if (@enumToInt(order) < @enumToInt(std.builtin.AtomicOrder.Acquire)) {
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
}
fn zirUnreachable(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {
- const tracy = trace(@src());
- defer tracy.end();
-
const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable";
const src = inst_data.src();
+
+ if (block.is_comptime or inst_data.force_comptime) {
+ return sema.fail(block, src, "reached unreachable code", .{});
+ }
try sema.requireRuntimeBlock(block, src);
// TODO Add compile error for @optimizeFor occurring too late in a scope.
- try block.addUnreachable(src, inst_data.safety);
+ try block.addUnreachable(src, true);
return always_noreturn;
}
@@ -14143,12 +14137,11 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
return block.addBitCast(type_res, operand_coerced);
}
-fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
- const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
- const src = inst_data.src();
- const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
- const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
- const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
+fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
+ const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+ const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
+ const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
const operand = sema.resolveInst(extra.rhs);
const operand_ty = sema.typeOf(operand);
@@ -16006,15 +15999,24 @@ fn zirAwait(
sema: *Sema,
block: *Block,
inst: Zir.Inst.Index,
- is_nosuspend: bool,
) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
const src = inst_data.src();
- _ = is_nosuspend;
return sema.fail(block, src, "TODO: Sema.zirAwait", .{});
}
+fn zirAwaitNosuspend(
+ sema: *Sema,
+ block: *Block,
+ extended: Zir.Inst.Extended.InstData,
+) CompileError!Air.Inst.Ref {
+ const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
+ const src: LazySrcLoc = .{ .node_offset = extra.node };
+
+ return sema.fail(block, src, "TODO: Sema.zirAwaitNosuspend", .{});
+}
+
fn zirVarExtended(
sema: *Sema,
block: *Block,
@@ -16097,37 +16099,33 @@ fn zirVarExtended(
return result;
}
-fn zirFuncExtended(
- sema: *Sema,
- block: *Block,
- extended: Zir.Inst.Extended.InstData,
- inst: Zir.Inst.Index,
-) CompileError!Air.Inst.Ref {
+fn zirFuncExtended(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const tracy = trace(@src());
defer tracy.end();
- const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, extended.operand);
- const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
- const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node };
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = inst_data.src();
+ const extra = sema.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
+
+ const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = inst_data.src_node };
const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align
- const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
var extra_index: usize = extra.end;
- const lib_name: ?[]const u8 = if (small.has_lib_name) blk: {
+ const lib_name: ?[]const u8 = if (extra.data.bits.has_lib_name) blk: {
const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
extra_index += 1;
break :blk lib_name;
} else null;
- const cc: std.builtin.CallingConvention = if (small.has_cc) blk: {
+ const cc: std.builtin.CallingConvention = if (extra.data.bits.has_cc) blk: {
const cc_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
const cc_tv = try sema.resolveInstConst(block, cc_src, cc_ref);
break :blk cc_tv.val.toEnum(std.builtin.CallingConvention);
} else .Unspecified;
- const align_val: Value = if (small.has_align) blk: {
+ const align_val: Value = if (extra.data.bits.has_align) blk: {
const align_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
extra_index += 1;
const align_tv = try sema.resolveInstConst(block, align_src, align_ref);
@@ -16144,13 +16142,13 @@ fn zirFuncExtended(
src_locs = sema.code.extraData(Zir.Inst.Func.SrcLocs, extra_index).data;
}
- const is_var_args = small.is_var_args;
- const is_inferred_error = small.is_inferred_error;
- const is_extern = small.is_extern;
+ const is_var_args = extra.data.bits.is_var_args;
+ const is_inferred_error = extra.data.bits.is_inferred_error;
+ const is_extern = extra.data.bits.is_extern;
return sema.funcCommon(
block,
- extra.data.src_node,
+ inst_data.src_node,
inst,
ret_ty_body,
cc,
diff --git a/src/Zir.zig b/src/Zir.zig
index f4c62a6f24..9ef6d33b86 100644
--- a/src/Zir.zig
+++ b/src/Zir.zig
@@ -73,6 +73,7 @@ pub fn extraData(code: Zir, comptime T: type, index: usize) struct { data: T, en
i32 => @bitCast(i32, code.extra[i]),
Inst.Call.Flags => @bitCast(Inst.Call.Flags, code.extra[i]),
Inst.SwitchBlock.Bits => @bitCast(Inst.SwitchBlock.Bits, code.extra[i]),
+ Inst.ExtendedFunc.Bits => @bitCast(Inst.ExtendedFunc.Bits, code.extra[i]),
else => @compileError("bad field type"),
};
i += 1;
@@ -278,8 +279,6 @@ pub const Inst = struct {
/// break instruction in a block, and the target block is the parent.
/// Uses the `break` union field.
break_inline,
- /// Uses the `node` union field.
- breakpoint,
/// Function call.
/// Uses `pl_node`. AST node is the function call. Payload is `Call`.
call,
@@ -331,6 +330,10 @@ pub const Inst = struct {
/// Same as `dbg_var_ptr` but the local is always a const and the operand
/// is the local's value.
dbg_var_val,
+ /// Marks the beginning of a semantic scope for debug info variables.
+ dbg_block_begin,
+ /// Marks the end of a semantic scope for debug info variables.
+ dbg_block_end,
/// Uses a name to identify a Decl and takes a pointer to it.
/// Uses the `str_tok` union field.
decl_ref,
@@ -413,6 +416,10 @@ pub const Inst = struct {
func,
/// Same as `func` but has an inferred error set.
func_inferred,
+ /// Represents a function declaration or function prototype, depending on
+ /// whether body_len is 0.
+ /// Uses the `pl_node` union field. `payload_index` points to a `ExtendedFunc`.
+ func_extended,
/// Implements the `@import` builtin.
/// Uses the `str_tok` field.
import,
@@ -499,6 +506,12 @@ pub const Inst = struct {
/// this instruction; a following 'ret' instruction will do the diversion.
/// Uses the `str_tok` union field.
ret_err_value_code,
+ /// Obtains a pointer to the return value.
+ /// Uses the `node` union field.
+ ret_ptr,
+ /// Obtains the return type of the in-scope function.
+ /// Uses the `node` union field.
+ ret_type,
/// Create a pointer type that does not have a sentinel, alignment, address space, or bit range specified.
/// Uses the `ptr_type_simple` union field.
ptr_type_simple,
@@ -744,8 +757,6 @@ pub const Inst = struct {
size_of,
/// Implements the `@bitSizeOf` builtin. Uses `un_node`.
bit_size_of,
- /// Implements the `@fence` builtin. Uses `un_node`.
- fence,
/// Implement builtin `@ptrToInt`. Uses `un_node`.
/// Convert a pointer to a `usize` integer.
@@ -774,12 +785,8 @@ pub const Inst = struct {
error_name,
/// Implement builtin `@panic`. Uses `un_node`.
panic,
- /// Implement builtin `@setAlignStack`. Uses `un_node`.
- set_align_stack,
/// Implement builtin `@setCold`. Uses `un_node`.
set_cold,
- /// Implement builtin `@setFloatMode`. Uses `un_node`.
- set_float_mode,
/// Implement builtin `@setRuntimeSafety`. Uses `un_node`.
set_runtime_safety,
/// Implement builtin `@sqrt`. Uses `un_node`.
@@ -843,9 +850,6 @@ pub const Inst = struct {
/// Convert an integer value to another integer type, asserting that the destination type
/// can hold the same mathematical value.
int_cast,
- /// Implements the `@errSetCast` builtin.
- /// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
- err_set_cast,
/// Implements the `@ptrCast` builtin.
/// Uses `pl_node` with payload `Bin`. `lhs` is dest type, `rhs` is operand.
ptr_cast,
@@ -972,7 +976,6 @@ pub const Inst = struct {
/// Implements `resume` syntax. Uses `un_node` field.
@"resume",
@"await",
- await_nosuspend,
/// When a type or function refers to a comptime value from an outer
/// scope, that forms a closure over comptime value. The outer scope
@@ -1028,8 +1031,6 @@ pub const Inst = struct {
.bool_br_and,
.bool_br_or,
.bool_not,
- .breakpoint,
- .fence,
.call,
.cmp_lt,
.cmp_lte,
@@ -1044,6 +1045,8 @@ pub const Inst = struct {
.dbg_stmt,
.dbg_var_ptr,
.dbg_var_val,
+ .dbg_block_begin,
+ .dbg_block_end,
.decl_ref,
.decl_val,
.load,
@@ -1064,6 +1067,7 @@ pub const Inst = struct {
.field_val_named,
.func,
.func_inferred,
+ .func_extended,
.has_decl,
.int,
.int_big,
@@ -1164,9 +1168,7 @@ pub const Inst = struct {
.bool_to_int,
.embed_file,
.error_name,
- .set_align_stack,
.set_cold,
- .set_float_mode,
.set_runtime_safety,
.sqrt,
.sin,
@@ -1192,7 +1194,6 @@ pub const Inst = struct {
.int_to_ptr,
.float_cast,
.int_cast,
- .err_set_cast,
.ptr_cast,
.truncate,
.align_cast,
@@ -1231,11 +1232,12 @@ pub const Inst = struct {
.c_import,
.@"resume",
.@"await",
- .await_nosuspend,
.ret_err_value_code,
.extended,
.closure_get,
.closure_capture,
+ .ret_ptr,
+ .ret_type,
=> false,
.@"break",
@@ -1258,13 +1260,13 @@ pub const Inst = struct {
/// AstGen uses this to find out if `Ref.void_value` should be used in place
/// of the result of a given instruction. This allows Sema to forego adding
/// the instruction to the map after analysis.
- pub fn isAlwaysVoid(tag: Tag) bool {
+ pub fn isAlwaysVoid(tag: Tag, data: Data) bool {
return switch (tag) {
- .breakpoint,
- .fence,
.dbg_stmt,
.dbg_var_ptr,
.dbg_var_val,
+ .dbg_block_begin,
+ .dbg_block_end,
.ensure_result_used,
.ensure_result_non_error,
.ensure_err_payload_void,
@@ -1283,9 +1285,7 @@ pub const Inst = struct {
.validate_array_init_comptime,
.@"export",
.export_value,
- .set_align_stack,
.set_cold,
- .set_float_mode,
.set_runtime_safety,
.memcpy,
.memset,
@@ -1353,6 +1353,7 @@ pub const Inst = struct {
.field_val_named,
.func,
.func_inferred,
+ .func_extended,
.has_decl,
.int,
.int_big,
@@ -1464,7 +1465,6 @@ pub const Inst = struct {
.int_to_ptr,
.float_cast,
.int_cast,
- .err_set_cast,
.ptr_cast,
.truncate,
.align_cast,
@@ -1500,9 +1500,7 @@ pub const Inst = struct {
.c_import,
.@"resume",
.@"await",
- .await_nosuspend,
.ret_err_value_code,
- .extended,
.closure_get,
.closure_capture,
.@"break",
@@ -1514,11 +1512,18 @@ pub const Inst = struct {
.ret_load,
.ret_tok,
.ret_err_value,
+ .ret_ptr,
+ .ret_type,
.@"unreachable",
.repeat,
.repeat_inline,
.panic,
=> false,
+
+ .extended => switch (data.extended.opcode) {
+ .breakpoint, .fence => true,
+ else => false,
+ },
};
}
@@ -1563,7 +1568,6 @@ pub const Inst = struct {
.bool_br_or = .bool_br,
.@"break" = .@"break",
.break_inline = .@"break",
- .breakpoint = .node,
.call = .pl_node,
.cmp_lt = .pl_node,
.cmp_lte = .pl_node,
@@ -1580,6 +1584,8 @@ pub const Inst = struct {
.dbg_stmt = .dbg_stmt,
.dbg_var_ptr = .str_op,
.dbg_var_val = .str_op,
+ .dbg_block_begin = .tok,
+ .dbg_block_end = .tok,
.decl_ref = .str_tok,
.decl_val = .str_tok,
.load = .un_node,
@@ -1602,6 +1608,7 @@ pub const Inst = struct {
.field_call_bind = .pl_node,
.func = .pl_node,
.func_inferred = .pl_node,
+ .func_extended = .pl_node,
.import = .str_tok,
.int = .int,
.int_big = .str,
@@ -1623,6 +1630,8 @@ pub const Inst = struct {
.ret_tok = .un_tok,
.ret_err_value = .str_tok,
.ret_err_value_code = .str_tok,
+ .ret_ptr = .node,
+ .ret_type = .node,
.ptr_type_simple = .ptr_type_simple,
.ptr_type = .ptr_type,
.slice_start = .pl_node,
@@ -1685,7 +1694,6 @@ pub const Inst = struct {
.type_info = .un_node,
.size_of = .un_node,
.bit_size_of = .un_node,
- .fence = .un_node,
.ptr_to_int = .un_node,
.error_to_int = .un_node,
@@ -1698,9 +1706,7 @@ pub const Inst = struct {
.embed_file = .un_node,
.error_name = .un_node,
.panic = .un_node,
- .set_align_stack = .un_node,
.set_cold = .un_node,
- .set_float_mode = .un_node,
.set_runtime_safety = .un_node,
.sqrt = .un_node,
.sin = .un_node,
@@ -1728,7 +1734,6 @@ pub const Inst = struct {
.int_to_enum = .pl_node,
.float_cast = .pl_node,
.int_cast = .pl_node,
- .err_set_cast = .pl_node,
.ptr_cast = .pl_node,
.truncate = .pl_node,
.align_cast = .pl_node,
@@ -1788,7 +1793,6 @@ pub const Inst = struct {
.@"resume" = .un_node,
.@"await" = .un_node,
- .await_nosuspend = .un_node,
.closure_capture = .un_tok,
.closure_get = .inst_node,
@@ -1806,11 +1810,6 @@ pub const Inst = struct {
/// Rarer instructions are here; ones that do not fit in the 8-bit `Tag` enum.
/// `noreturn` instructions may not go here; they must be part of the main `Tag` enum.
pub const Extended = enum(u16) {
- /// Represents a function declaration or function prototype, depending on
- /// whether body_len is 0.
- /// `operand` is payload index to `ExtendedFunc`.
- /// `small` is `ExtendedFunc.Small`.
- func,
/// Declares a global variable.
/// `operand` is payload index to `ExtendedVar`.
/// `small` is `ExtendedVar.Small`.
@@ -1834,12 +1833,6 @@ pub const Inst = struct {
/// `operand` is payload index to `OpaqueDecl`.
/// `small` is `OpaqueDecl.Small`.
opaque_decl,
- /// Obtains a pointer to the return value.
- /// `operand` is `src_node: i32`.
- ret_ptr,
- /// Obtains the return type of the in-scope function.
- /// `operand` is `src_node: i32`.
- ret_type,
/// Implements the `@This` builtin.
/// `operand` is `src_node: i32`.
this,
@@ -1917,10 +1910,6 @@ pub const Inst = struct {
/// The `@prefetch` builtin.
/// `operand` is payload index to `BinNode`.
prefetch,
- /// Marks the beginning of a semantic scope for debug info variables.
- dbg_block_begin,
- /// Marks the end of a semantic scope for debug info variables.
- dbg_block_end,
/// Given a pointer to a struct or object that contains virtual fields, returns the
/// named field. If there is no named field, searches in the type for a decl that
/// matches the field name. The decl is resolved and we ensure that it's a function
@@ -1931,6 +1920,22 @@ pub const Inst = struct {
/// `builtin_call` instruction. Any other use is invalid zir and may crash the compiler.
/// Uses `pl_node` field. The AST node is the `@field` builtin. Payload is FieldNamedNode.
field_call_bind_named,
+ /// Implements the `@fence` builtin.
+ /// `operand` is payload index to `UnNode`.
+ fence,
+ /// Implement builtin `@setFloatMode`.
+ /// `operand` is payload index to `UnNode`.
+ set_float_mode,
+ /// Implement builtin `@setAlignStack`.
+ /// `operand` is payload index to `UnNode`.
+ set_align_stack,
+ /// Implements the `@errSetCast` builtin.
+ /// `operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
+ err_set_cast,
+ /// `operand` is payload index to `UnNode`.
+ await_nosuspend,
+ /// `operand` is `src_node: i32`.
+ breakpoint,
pub const InstData = struct {
opcode: Extended,
@@ -2502,11 +2507,7 @@ pub const Inst = struct {
/// Offset from Decl AST node index.
/// `Tag` determines which kind of AST node this points to.
src_node: i32,
- /// `false`: Not safety checked - the compiler will assume the
- /// correctness of this instruction.
- /// `true`: In safety-checked modes, this will generate a call
- /// to the panic function unless it can be proven unreachable by the compiler.
- safety: bool,
+ force_comptime: bool,
pub fn src(self: @This()) LazySrcLoc {
return .{ .node_offset = self.src_node };
@@ -2623,14 +2624,14 @@ pub const Inst = struct {
/// 4. body: Index // for each body_len
/// 5. src_locs: Func.SrcLocs // if body_len != 0
pub const ExtendedFunc = struct {
- src_node: i32,
/// If this is 0 it means a void return type.
ret_body_len: u32,
/// Points to the block that contains the param instructions for this function.
param_block: Index,
body_len: u32,
+ bits: Bits,
- pub const Small = packed struct {
+ pub const Bits = packed struct {
is_var_args: bool,
is_inferred_error: bool,
has_lib_name: bool,
@@ -2638,7 +2639,7 @@ pub const Inst = struct {
has_align: bool,
is_test: bool,
is_extern: bool,
- _: u9 = undefined,
+ _: u25 = undefined,
};
};
@@ -3462,14 +3463,11 @@ pub fn declIterator(zir: Zir, decl_inst: u32) DeclIterator {
switch (tags[decl_inst]) {
// Functions are allowed and yield no iterations.
// There is one case matching this in the extended instruction set below.
- .func,
- .func_inferred,
- => return declIteratorInner(zir, 0, 0),
+ .func, .func_inferred, .func_extended => return declIteratorInner(zir, 0, 0),
.extended => {
const extended = datas[decl_inst].extended;
switch (extended.opcode) {
- .func => return declIteratorInner(zir, 0, 0),
.struct_decl => {
const small = @bitCast(Inst.StructDecl.Small, extended.small);
var extra_index: usize = extended.operand;
@@ -3574,21 +3572,21 @@ fn findDeclsInner(
const body = zir.extra[extra.end..][0..extra.data.body_len];
return zir.findDeclsBody(list, body);
},
+ .func_extended => {
+ try list.append(inst);
+
+ const inst_data = datas[inst].pl_node;
+ const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index);
+ var extra_index: usize = extra.end;
+ extra_index += @boolToInt(extra.data.bits.has_lib_name);
+ extra_index += @boolToInt(extra.data.bits.has_cc);
+ extra_index += @boolToInt(extra.data.bits.has_align);
+ const body = zir.extra[extra_index..][0..extra.data.body_len];
+ return zir.findDeclsBody(list, body);
+ },
.extended => {
const extended = datas[inst].extended;
switch (extended.opcode) {
- .func => {
- try list.append(inst);
-
- const extra = zir.extraData(Inst.ExtendedFunc, extended.operand);
- const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
- var extra_index: usize = extra.end;
- extra_index += @boolToInt(small.has_lib_name);
- extra_index += @boolToInt(small.has_cc);
- extra_index += @boolToInt(small.has_align);
- const body = zir.extra[extra_index..][0..extra.data.body_len];
- return zir.findDeclsBody(list, body);
- },
// Decl instructions are interesting but have no body.
// 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 {
.body = body,
};
},
- .extended => blk: {
- const extended = datas[fn_inst].extended;
- assert(extended.opcode == .func);
- const extra = zir.extraData(Inst.ExtendedFunc, extended.operand);
- const small = @bitCast(Inst.ExtendedFunc.Small, extended.small);
+ .func_extended => blk: {
+ const inst_data = datas[fn_inst].pl_node;
+ const extra = zir.extraData(Inst.ExtendedFunc, inst_data.payload_index);
var extra_index: usize = extra.end;
- extra_index += @boolToInt(small.has_lib_name);
- extra_index += @boolToInt(small.has_cc);
- extra_index += @boolToInt(small.has_align);
+ extra_index += @boolToInt(extra.data.bits.has_lib_name);
+ extra_index += @boolToInt(extra.data.bits.has_cc);
+ extra_index += @boolToInt(extra.data.bits.has_align);
const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len];
extra_index += ret_ty_body.len;
const body = zir.extra[extra_index..][0..extra.data.body_len];
diff --git a/src/print_zir.zig b/src/print_zir.zig
index 776aeffbdc..ac90c26cf6 100644
--- a/src/print_zir.zig
+++ b/src/print_zir.zig
@@ -200,9 +200,7 @@ const Writer = struct {
.embed_file,
.error_name,
.panic,
- .set_align_stack,
.set_cold,
- .set_float_mode,
.set_runtime_safety,
.sqrt,
.sin,
@@ -231,8 +229,6 @@ const Writer = struct {
.elem_type,
.@"resume",
.@"await",
- .await_nosuspend,
- .fence,
.switch_cond,
.switch_cond_ref,
.array_base_ptr,
@@ -343,7 +339,6 @@ const Writer = struct {
.int_to_enum,
.float_cast,
.int_cast,
- .err_set_cast,
.ptr_cast,
.truncate,
.align_cast,
@@ -405,13 +400,14 @@ const Writer = struct {
.as_node => try self.writeAs(stream, inst),
- .breakpoint,
.repeat,
.repeat_inline,
.alloc_inferred,
.alloc_inferred_mut,
.alloc_inferred_comptime,
.alloc_inferred_comptime_mut,
+ .ret_ptr,
+ .ret_type,
=> try self.writeNode(stream, inst),
.error_value,
@@ -433,6 +429,7 @@ const Writer = struct {
.func => try self.writeFunc(stream, inst, false),
.func_inferred => try self.writeFunc(stream, inst, true),
+ .func_extended => try self.writeFuncExtended(stream, inst),
.@"unreachable" => try self.writeUnreachable(stream, inst),
@@ -444,6 +441,10 @@ const Writer = struct {
.dbg_stmt => try self.writeDbgStmt(stream, inst),
+ .dbg_block_begin,
+ .dbg_block_end,
+ => try stream.writeAll("))"),
+
.closure_get => try self.writeInstNode(stream, inst),
.extended => try self.writeExtended(stream, inst),
@@ -454,13 +455,12 @@ const Writer = struct {
const extended = self.code.instructions.items(.data)[inst].extended;
try stream.print("{s}(", .{@tagName(extended.opcode)});
switch (extended.opcode) {
- .ret_ptr,
- .ret_type,
.this,
.ret_addr,
.error_return_trace,
.frame,
.frame_address,
+ .breakpoint,
=> try self.writeExtNode(stream, extended),
.builtin_src => {
@@ -469,12 +469,7 @@ const Writer = struct {
try stream.print(":{d}:{d}", .{ inst_data.line + 1, inst_data.column + 1 });
},
- .dbg_block_begin,
- .dbg_block_end,
- => try stream.writeAll("))"),
-
.@"asm" => try self.writeAsm(stream, extended),
- .func => try self.writeFuncExtended(stream, extended),
.variable => try self.writeVarExtended(stream, extended),
.alloc => try self.writeAllocExtended(stream, extended),
@@ -492,7 +487,14 @@ const Writer = struct {
.enum_decl => try self.writeEnumDecl(stream, extended),
.opaque_decl => try self.writeOpaqueDecl(stream, extended),
- .c_undef, .c_include, .wasm_memory_size => {
+ .await_nosuspend,
+ .c_undef,
+ .c_include,
+ .fence,
+ .set_float_mode,
+ .set_align_stack,
+ .wasm_memory_size,
+ => {
const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
const src: LazySrcLoc = .{ .node_offset = inst_data.node };
try self.writeInstRef(stream, inst_data.operand);
@@ -500,7 +502,12 @@ const Writer = struct {
try self.writeSrc(stream, src);
},
- .builtin_extern, .c_define, .wasm_memory_grow, .prefetch => {
+ .builtin_extern,
+ .c_define,
+ .err_set_cast,
+ .wasm_memory_grow,
+ .prefetch,
+ => {
const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
const src: LazySrcLoc = .{ .node_offset = inst_data.node };
try self.writeInstRef(stream, inst_data.lhs);
@@ -1913,24 +1920,24 @@ const Writer = struct {
);
}
- fn writeFuncExtended(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void {
- const extra = self.code.extraData(Zir.Inst.ExtendedFunc, extended.operand);
- const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
- const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
+ fn writeFuncExtended(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
+ const inst_data = self.code.instructions.items(.data)[inst].pl_node;
+ const extra = self.code.extraData(Zir.Inst.ExtendedFunc, inst_data.payload_index);
+ const src = inst_data.src();
var extra_index: usize = extra.end;
- if (small.has_lib_name) {
+ if (extra.data.bits.has_lib_name) {
const lib_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
extra_index += 1;
try stream.print("lib_name=\"{}\", ", .{std.zig.fmtEscapes(lib_name)});
}
- try self.writeFlag(stream, "test, ", small.is_test);
- const cc: Zir.Inst.Ref = if (!small.has_cc) .none else blk: {
+ try self.writeFlag(stream, "test, ", extra.data.bits.is_test);
+ const cc: Zir.Inst.Ref = if (!extra.data.bits.has_cc) .none else blk: {
const cc = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
extra_index += 1;
break :blk cc;
};
- const align_inst: Zir.Inst.Ref = if (!small.has_align) .none else blk: {
+ const align_inst: Zir.Inst.Ref = if (!extra.data.bits.has_align) .none else blk: {
const align_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
extra_index += 1;
break :blk align_inst;
@@ -1949,9 +1956,9 @@ const Writer = struct {
return self.writeFuncCommon(
stream,
ret_ty_body,
- small.is_inferred_error,
- small.is_var_args,
- small.is_extern,
+ extra.data.bits.is_inferred_error,
+ extra.data.bits.is_var_args,
+ extra.data.bits.is_extern,
cc,
align_inst,
body,
@@ -2091,8 +2098,6 @@ const Writer = struct {
fn writeUnreachable(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].@"unreachable";
- const safety_str = if (inst_data.safety) "safe" else "unsafe";
- try stream.print("{s}) ", .{safety_str});
try self.writeSrc(stream, inst_data.src());
}