aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 972a19de4f..28a012bfb1 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -926,6 +926,8 @@ fn analyzeBodyInner(
.ret_ptr => try sema.zirRetPtr(block, inst),
.ret_type => try sema.addType(sema.fn_ret_ty),
+ .save_err_ret_index => try sema.zirSaveErrRetIndex(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.
@@ -1208,6 +1210,11 @@ fn analyzeBodyInner(
i += 1;
continue;
},
+ .restore_err_ret_index => {
+ try sema.zirRestoreErrRetIndex(block, inst);
+ i += 1;
+ continue;
+ },
// Special case instructions to handle comptime control flow.
.@"break" => {
@@ -16176,6 +16183,52 @@ fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
backend_supports_error_return_tracing;
}
+fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
+ const inst_data = sema.code.instructions.items(.data)[inst].node;
+ const src = LazySrcLoc.nodeOffset(inst_data);
+
+ // This is only relevant at runtime.
+ if (block.is_comptime) return Air.Inst.Ref.zero_usize;
+
+ const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
+ const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and
+ sema.mod.comp.bin_file.options.error_return_tracing and
+ backend_supports_error_return_tracing;
+ if (!ok) return Air.Inst.Ref.zero_usize;
+
+ const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
+ const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
+ const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
+ const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
+ return sema.fieldVal(block, src, err_return_trace, "index", src);
+}
+
+fn zirRestoreErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src = inst_data.src();
+
+ // This is only relevant at runtime.
+ if (block.is_comptime) return;
+
+ const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
+ const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and
+ sema.mod.comp.bin_file.options.error_return_tracing and
+ backend_supports_error_return_tracing;
+ if (!ok) return;
+
+ const operand = if (inst_data.operand != .none)
+ try sema.resolveInst(inst_data.operand)
+ else
+ .zero_usize;
+
+ const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
+ const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
+ const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
+ const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
+ const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, "index", src, stack_trace_ty, true);
+ try sema.storePtr2(block, src, field_ptr, src, operand, src, .store);
+}
+
fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
assert(sema.fn_ret_ty.zigTypeTag() == .ErrorUnion);
@@ -17181,8 +17234,6 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
- const src = inst_data.src();
- _ = src;
const operand = try sema.resolveInst(inst_data.operand);
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };