commit 3fa226a80c99dadab91538ef450b22230da9c21f (tree)
parent 283c92e3628a831b6be7d4ef79628b55ce8b6817
Author: Cody Tapscott <topolarity@tapscott.me>
Date: Mon, 21 Nov 2022 08:57:40 -0700
AstGen: Pop error trace for `continue`
PR #12837 handled control flow for break and return, but I forgot
about `continue`. This is effectively another break, so we just
need another `.restore_err_ret_index` ZIR instruction.
Resolves #13618.
Diffstat:
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/src/AstGen.zig b/src/AstGen.zig
@@ -2071,6 +2071,11 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
if (break_tag == .break_inline) {
_ = try parent_gz.addUnNode(.check_comptime_control_flow, Zir.indexToRef(continue_block), node);
}
+
+ // As our last action before the continue, "pop" the error trace if needed
+ if (!gen_zir.force_comptime)
+ _ = try parent_gz.addRestoreErrRetIndex(.{ .block = continue_block }, .always);
+
_ = try parent_gz.addBreak(break_tag, continue_block, .void_value);
return Zir.Inst.Ref.unreachable_value;
},
diff --git a/test/stack_traces.zig b/test/stack_traces.zig
@@ -152,6 +152,57 @@ pub fn addCases(cases: *tests.StackTracesContext) void {
});
cases.addCase(.{
+ .name = "continue in while loop",
+ .source =
+ \\fn foo() !void {
+ \\ return error.UhOh;
+ \\}
+ \\
+ \\pub fn main() !void {
+ \\ var i: usize = 0;
+ \\ while (i < 3) : (i += 1) {
+ \\ foo() catch continue;
+ \\ }
+ \\ return error.UnrelatedError;
+ \\}
+ ,
+ .Debug = .{
+ .expect =
+ \\error: UnrelatedError
+ \\source.zig:10:5: [address] in main (test)
+ \\ return error.UnrelatedError;
+ \\ ^
+ \\
+ ,
+ },
+ .ReleaseSafe = .{
+ .exclude_os = .{
+ .windows, // TODO
+ .linux, // defeated by aggressive inlining
+ },
+ .expect =
+ \\error: UnrelatedError
+ \\source.zig:10:5: [address] in [function]
+ \\ return error.UnrelatedError;
+ \\ ^
+ \\
+ ,
+ },
+ .ReleaseFast = .{
+ .expect =
+ \\error: UnrelatedError
+ \\
+ ,
+ },
+ .ReleaseSmall = .{
+ .expect =
+ \\error: UnrelatedError
+ \\
+ ,
+ },
+ });
+
+ cases.addCase(.{
.name = "try return + handled catch/if-else",
.source =
\\fn foo() !void {