Skip to content

Commit 6ecf3b1

Browse files
authored
Merge pull request #18599 from dweiller/err-union-switch-err-trace
astgen: fix error return trace on error union switch
2 parents 7d81c95 + c4cff44 commit 6ecf3b1

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/AstGen.zig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6919,6 +6919,8 @@ fn switchExprErrUnion(
69196919
};
69206920
assert(node_tags[switch_node] == .@"switch" or node_tags[switch_node] == .switch_comma);
69216921

6922+
const do_err_trace = astgen.fn_block != null;
6923+
69226924
const extra = tree.extraData(node_datas[switch_node].rhs, Ast.Node.SubRange);
69236925
const case_nodes = tree.extra_data[extra.start..extra.end];
69246926

@@ -7304,10 +7306,14 @@ fn switchExprErrUnion(
73047306
case_scope.instructions_top = parent_gz.instructions.items.len;
73057307
defer case_scope.unstack();
73067308

7309+
if (do_err_trace and nodeMayAppendToErrorTrace(tree, operand_node))
7310+
_ = try case_scope.addSaveErrRetIndex(.always);
7311+
73077312
try case_scope.addDbgBlockBegin();
73087313
if (dbg_var_name != .empty) {
73097314
try case_scope.addDbgVar(.dbg_var_val, dbg_var_name, dbg_var_inst);
73107315
}
7316+
73117317
const target_expr_node = case.ast.target_expr;
73127318
const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, target_expr_node);
73137319
// check capture_scope, not err_scope to avoid false positive unused error capture
@@ -7318,7 +7324,17 @@ fn switchExprErrUnion(
73187324
any_uses_err_capture = true;
73197325
}
73207326
try case_scope.addDbgBlockEnd();
7327+
73217328
if (!parent_gz.refIsNoReturn(case_result)) {
7329+
if (do_err_trace)
7330+
try restoreErrRetIndex(
7331+
&case_scope,
7332+
.{ .block = switch_block },
7333+
block_scope.break_result_info,
7334+
target_expr_node,
7335+
case_result,
7336+
);
7337+
73227338
_ = try case_scope.addBreakWithSrcNode(.@"break", switch_block, case_result, target_expr_node);
73237339
}
73247340

src/Sema.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13117,6 +13117,7 @@ fn validateErrSetSwitch(
1311713117
.defer_err_code,
1311813118
.err_union_code,
1311913119
.ret_err_value_code,
13120+
.save_err_ret_index,
1312013121
.restore_err_ret_index,
1312113122
.is_non_err,
1312213123
.ret_is_non_err,

test/stack_traces.zig

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,4 +807,59 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
807807
,
808808
},
809809
});
810+
cases.addCase(.{
811+
.name = "error union switch with call operand",
812+
.source =
813+
\\pub fn main() !void {
814+
\\ try foo();
815+
\\ return error.TheSkyIsFalling;
816+
\\}
817+
\\
818+
\\noinline fn failure() error{ Fatal, NonFatal }!void {
819+
\\ return error.NonFatal;
820+
\\}
821+
\\
822+
\\fn foo() error{Fatal}!void {
823+
\\ return failure() catch |err| switch (err) {
824+
\\ error.Fatal => return error.Fatal,
825+
\\ error.NonFatal => return,
826+
\\ };
827+
\\}
828+
,
829+
.Debug = .{
830+
.expect =
831+
\\error: TheSkyIsFalling
832+
\\source.zig:3:5: [address] in main (test)
833+
\\ return error.TheSkyIsFalling;
834+
\\ ^
835+
\\
836+
,
837+
},
838+
.ReleaseSafe = .{
839+
.exclude_os = &.{
840+
.windows, // TODO
841+
.linux, // defeated by aggressive inlining
842+
},
843+
.expect =
844+
\\error: TheSkyIsFalling
845+
\\source.zig:3:5: [address] in [function]
846+
\\ return error.TheSkyIsFalling;
847+
\\ ^
848+
\\
849+
,
850+
.error_tracing = true,
851+
},
852+
.ReleaseFast = .{
853+
.expect =
854+
\\error: TheSkyIsFalling
855+
\\
856+
,
857+
},
858+
.ReleaseSmall = .{
859+
.expect =
860+
\\error: TheSkyIsFalling
861+
\\
862+
,
863+
},
864+
});
810865
}

0 commit comments

Comments
 (0)