mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
3fa226a80c
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.
798 lines
22 KiB
Zig
798 lines
22 KiB
Zig
const std = @import("std");
|
|
const os = std.os;
|
|
const tests = @import("tests.zig");
|
|
|
|
pub fn addCases(cases: *tests.StackTracesContext) void {
|
|
cases.addCase(.{
|
|
.name = "return",
|
|
.source =
|
|
\\pub fn main() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:2:5: [address] in main (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "try return",
|
|
.source =
|
|
\\fn foo() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ try foo();
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:2:5: [address] in foo (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in main (test)
|
|
\\ try foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
},
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in [function]
|
|
\\ try foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
cases.addCase(.{
|
|
.name = "non-error return pops error trace",
|
|
.source =
|
|
\\fn bar() !void {
|
|
\\ return error.UhOh;
|
|
\\}
|
|
\\
|
|
\\fn foo() !void {
|
|
\\ bar() catch {
|
|
\\ return; // non-error result: success
|
|
\\ };
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ try foo();
|
|
\\ return error.UnrelatedError;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: UnrelatedError
|
|
\\source.zig:13:5: [address] in main (test)
|
|
\\ return error.UnrelatedError;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: UnrelatedError
|
|
\\source.zig:13:5: [address] in [function]
|
|
\\ return error.UnrelatedError;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: UnrelatedError
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: UnrelatedError
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
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 {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ foo() catch {}; // should not affect error trace
|
|
\\ if (foo()) |_| {} else |_| {
|
|
\\ // should also not affect error trace
|
|
\\ }
|
|
\\ try foo();
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:2:5: [address] in foo (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:10:5: [address] in main (test)
|
|
\\ try foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:10:5: [address] in [function]
|
|
\\ try foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "break from inline loop pops error return trace",
|
|
.source =
|
|
\\fn foo() !void { return error.FooBar; }
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ comptime var i: usize = 0;
|
|
\\ b: inline while (i < 5) : (i += 1) {
|
|
\\ foo() catch {
|
|
\\ break :b; // non-error break, success
|
|
\\ };
|
|
\\ }
|
|
\\ // foo() was successfully handled, should not appear in trace
|
|
\\
|
|
\\ return error.BadTime;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: BadTime
|
|
\\source.zig:12:5: [address] in main (test)
|
|
\\ return error.BadTime;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: BadTime
|
|
\\source.zig:12:5: [address] in [function]
|
|
\\ return error.BadTime;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: BadTime
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: BadTime
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "catch and re-throw error",
|
|
.source =
|
|
\\fn foo() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ return foo() catch error.AndMyCarIsOutOfGas;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\source.zig:2:5: [address] in foo (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in main (test)
|
|
\\ return foo() catch error.AndMyCarIsOutOfGas;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in [function]
|
|
\\ return foo() catch error.AndMyCarIsOutOfGas;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "errors stored in var do not contribute to error trace",
|
|
.source =
|
|
\\fn foo() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ // Once an error is stored in a variable, it is popped from the trace
|
|
\\ var x = foo();
|
|
\\ x = {};
|
|
\\
|
|
\\ // As a result, this error trace will still be clean
|
|
\\ return error.SomethingUnrelatedWentWrong;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: SomethingUnrelatedWentWrong
|
|
\\source.zig:11:5: [address] in main (test)
|
|
\\ return error.SomethingUnrelatedWentWrong;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: SomethingUnrelatedWentWrong
|
|
\\source.zig:11:5: [address] in [function]
|
|
\\ return error.SomethingUnrelatedWentWrong;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: SomethingUnrelatedWentWrong
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: SomethingUnrelatedWentWrong
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "error stored in const has trace preserved for duration of block",
|
|
.source =
|
|
\\fn foo() !void { return error.TheSkyIsFalling; }
|
|
\\fn bar() !void { return error.InternalError; }
|
|
\\fn baz() !void { return error.UnexpectedReality; }
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ const x = foo();
|
|
\\ const y = b: {
|
|
\\ if (true)
|
|
\\ break :b bar();
|
|
\\
|
|
\\ break :b {};
|
|
\\ };
|
|
\\ x catch {};
|
|
\\ y catch {};
|
|
\\ // foo()/bar() error traces not popped until end of block
|
|
\\
|
|
\\ {
|
|
\\ const z = baz();
|
|
\\ z catch {};
|
|
\\ // baz() error trace still alive here
|
|
\\ }
|
|
\\ // baz() error trace popped, foo(), bar() still alive
|
|
\\ return error.StillUnresolved;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: StillUnresolved
|
|
\\source.zig:1:18: [address] in foo (test)
|
|
\\fn foo() !void { return error.TheSkyIsFalling; }
|
|
\\ ^
|
|
\\source.zig:2:18: [address] in bar (test)
|
|
\\fn bar() !void { return error.InternalError; }
|
|
\\ ^
|
|
\\source.zig:23:5: [address] in main (test)
|
|
\\ return error.StillUnresolved;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
.linux, // defeated by aggressive inlining
|
|
},
|
|
.expect =
|
|
\\error: StillUnresolved
|
|
\\source.zig:1:18: [address] in [function]
|
|
\\fn foo() !void { return error.TheSkyIsFalling; }
|
|
\\ ^
|
|
\\source.zig:2:18: [address] in [function]
|
|
\\fn bar() !void { return error.InternalError; }
|
|
\\ ^
|
|
\\source.zig:23:5: [address] in [function]
|
|
\\ return error.StillUnresolved;
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: StillUnresolved
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: StillUnresolved
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "error passed to function has its trace preserved for duration of the call",
|
|
.source =
|
|
\\pub fn expectError(expected_error: anyerror, actual_error: anyerror!void) !void {
|
|
\\ actual_error catch |err| {
|
|
\\ if (err == expected_error) return {};
|
|
\\ };
|
|
\\ return error.TestExpectedError;
|
|
\\}
|
|
\\
|
|
\\fn alwaysErrors() !void { return error.ThisErrorShouldNotAppearInAnyTrace; }
|
|
\\fn foo() !void { return error.Foo; }
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ try expectError(error.ThisErrorShouldNotAppearInAnyTrace, alwaysErrors());
|
|
\\ try expectError(error.ThisErrorShouldNotAppearInAnyTrace, alwaysErrors());
|
|
\\ try expectError(error.Foo, foo());
|
|
\\
|
|
\\ // Only the error trace for this failing check should appear:
|
|
\\ try expectError(error.Bar, foo());
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: TestExpectedError
|
|
\\source.zig:9:18: [address] in foo (test)
|
|
\\fn foo() !void { return error.Foo; }
|
|
\\ ^
|
|
\\source.zig:5:5: [address] in expectError (test)
|
|
\\ return error.TestExpectedError;
|
|
\\ ^
|
|
\\source.zig:17:5: [address] in main (test)
|
|
\\ try expectError(error.Bar, foo());
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
},
|
|
.expect =
|
|
\\error: TestExpectedError
|
|
\\source.zig:9:18: [address] in [function]
|
|
\\fn foo() !void { return error.Foo; }
|
|
\\ ^
|
|
\\source.zig:5:5: [address] in [function]
|
|
\\ return error.TestExpectedError;
|
|
\\ ^
|
|
\\source.zig:17:5: [address] in [function]
|
|
\\ try expectError(error.Bar, foo());
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: TestExpectedError
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: TestExpectedError
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "try return from within catch",
|
|
.source =
|
|
\\fn foo() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\fn bar() !void {
|
|
\\ return error.AndMyCarIsOutOfGas;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ foo() catch { // error trace should include foo()
|
|
\\ try bar();
|
|
\\ };
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\source.zig:2:5: [address] in foo (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in bar (test)
|
|
\\ return error.AndMyCarIsOutOfGas;
|
|
\\ ^
|
|
\\source.zig:11:9: [address] in main (test)
|
|
\\ try bar();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
},
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in [function]
|
|
\\ return error.AndMyCarIsOutOfGas;
|
|
\\ ^
|
|
\\source.zig:11:9: [address] in [function]
|
|
\\ try bar();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "try return from within if-else",
|
|
.source =
|
|
\\fn foo() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\fn bar() !void {
|
|
\\ return error.AndMyCarIsOutOfGas;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ if (foo()) |_| {} else |_| { // error trace should include foo()
|
|
\\ try bar();
|
|
\\ }
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\source.zig:2:5: [address] in foo (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in bar (test)
|
|
\\ return error.AndMyCarIsOutOfGas;
|
|
\\ ^
|
|
\\source.zig:11:9: [address] in main (test)
|
|
\\ try bar();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
},
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in [function]
|
|
\\ return error.AndMyCarIsOutOfGas;
|
|
\\ ^
|
|
\\source.zig:11:9: [address] in [function]
|
|
\\ try bar();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: AndMyCarIsOutOfGas
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.name = "try try return return",
|
|
.source =
|
|
\\fn foo() !void {
|
|
\\ try bar();
|
|
\\}
|
|
\\
|
|
\\fn bar() !void {
|
|
\\ return make_error();
|
|
\\}
|
|
\\
|
|
\\fn make_error() !void {
|
|
\\ return error.TheSkyIsFalling;
|
|
\\}
|
|
\\
|
|
\\pub fn main() !void {
|
|
\\ try foo();
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:10:5: [address] in make_error (test)
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in bar (test)
|
|
\\ return make_error();
|
|
\\ ^
|
|
\\source.zig:2:5: [address] in foo (test)
|
|
\\ try bar();
|
|
\\ ^
|
|
\\source.zig:14:5: [address] in main (test)
|
|
\\ try foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSafe = .{
|
|
.exclude_os = .{
|
|
.windows, // TODO
|
|
},
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\source.zig:10:5: [address] in [function]
|
|
\\ return error.TheSkyIsFalling;
|
|
\\ ^
|
|
\\source.zig:6:5: [address] in [function]
|
|
\\ return make_error();
|
|
\\ ^
|
|
\\source.zig:2:5: [address] in [function]
|
|
\\ try bar();
|
|
\\ ^
|
|
\\source.zig:14:5: [address] in [function]
|
|
\\ try foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseFast = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
.ReleaseSmall = .{
|
|
.expect =
|
|
\\error: TheSkyIsFalling
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
|
|
cases.addCase(.{
|
|
.exclude_os = .{
|
|
.openbsd, // integer overflow
|
|
.windows, // TODO intermittent failures
|
|
},
|
|
.name = "dumpCurrentStackTrace",
|
|
.source =
|
|
\\const std = @import("std");
|
|
\\
|
|
\\fn bar() void {
|
|
\\ std.debug.dumpCurrentStackTrace(@returnAddress());
|
|
\\}
|
|
\\fn foo() void {
|
|
\\ bar();
|
|
\\}
|
|
\\pub fn main() u8 {
|
|
\\ foo();
|
|
\\ return 1;
|
|
\\}
|
|
,
|
|
.Debug = .{
|
|
.expect =
|
|
\\source.zig:7:8: [address] in foo (test)
|
|
\\ bar();
|
|
\\ ^
|
|
\\source.zig:10:8: [address] in main (test)
|
|
\\ foo();
|
|
\\ ^
|
|
\\
|
|
,
|
|
},
|
|
});
|
|
}
|