zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Msrc/AstGen.zig | 5+++++
Mtest/stack_traces.zig | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
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 {