╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ error_traces.zig ─────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
339 \\ // Once an error is stored in a variable, it is popped from the trace 340 \\ var x = foo(); 341 \\ x = {}; 342 \\ 343 \\ // As a result, this error trace will still be clean 344 \\ return error.SomethingUnrelatedWentWrong; 345 \\} 346 , 347 .expect_error = "SomethingUnrelatedWentWrong", 348 .expect_trace = 349 \\source.zig:11:5: [address] in main 350 \\ return error.SomethingUnrelatedWentWrong; 351 \\ ^ 352 , 353 }); 354 355 cases.addCase(.{ 356 .params = params, 357 .target = target, 358 .name = "error stored in const has trace preserved for duration of block", 359 .source = 360 \\fn foo() !void { return error.TheSkyIsFalling; } 361 \\fn bar() !void { return error.InternalError; } 362 \\fn baz() !void { return error.UnexpectedReality; } 363 \\ 364 \\pub fn main() !void { 365 \\ const x = foo(); 366 \\ const y = b: { 367 \\ if (true) 368 \\ break :b bar(); 369 \\ 370 \\ break :b {}; 371 \\ }; 372 \\ x catch {}; 373 \\ y catch {}; 374 \\ // foo()/bar() error traces not popped until end of block 375 \\ 376 \\ { 377 \\ const z = baz(); 378 \\ z catch {}; 379 \\ // baz() error trace still alive here 380 \\ } 381 \\ // baz() error trace popped, foo(), bar() still alive 382 \\ return error.StillUnresolved; 383 \\} 384 , 385 .expect_error = "StillUnresolved", 386 .expect_trace = 387 \\source.zig:1:18: [address] in foo 388 \\fn foo() !void { return error.TheSkyIsFalling; } 389 \\ ^ 390 \\source.zig:2:18: [address] in bar 391 \\fn bar() !void { return error.InternalError; } 392 \\ ^ 393 \\source.zig:23:5: [address] in main 394 \\ return error.StillUnresolved; 395 \\ ^ 396 , 397 .disable_trace_optimized = &.{ 398 .{ .x86_64, .windows }, 399 .{ .x86, .windows }, 400 .{ .x86_64, .macos }, 401 .{ .aarch64, .macos }, 402 }, 403 }); 404 405 cases.addCase(.{ 406 .params = params, 407 .target = target, 408 .name = "error passed to function has its trace preserved for duration of the call", 409 .source = 410 \\pub fn expectError(expected_error: anyerror, actual_error: anyerror!void) !void { 411 \\ actual_error catch |err| { 412 \\ if (err == expected_error) return {}; 413 \\ }; 414 \\ return error.TestExpectedError; 415 \\} 416 \\ 417 \\fn alwaysErrors() !void { return error.ThisErrorShouldNotAppearInAnyTrace; } 418 \\fn foo() !void { return error.Foo; } 419 \\ 420 \\pub fn main() !void { 421 \\ try expectError(error.ThisErrorShouldNotAppearInAnyTrace, alwaysErrors()); 422 \\ try expectError(error.ThisErrorShouldNotAppearInAnyTrace, alwaysErrors()); 423 \\ try expectError(error.Foo, foo()); 424 \\ 425 \\ // Only the error trace for this failing check should appear: 426 \\ try expectError(error.Bar, foo()); 427 \\} 428 , 429 .expect_error = "TestExpectedError", 430 .expect_trace = 431 \\source.zig:9:18: [address] in foo 432 \\fn foo() !void { return error.Foo; } 433 \\ ^ 434 \\source.zig:5:5: [address] in expectError 435 \\ return error.TestExpectedError; 436 \\ ^ 437 \\source.zig:17:5: [address] in main 438 \\ try expectError(error.Bar, foo()); 439 \\ ^ 440 , 441 .disable_trace_optimized = &.{ 442 .{ .x86_64, .windows }, 443 .{ .x86, .windows }, 444 .{ .x86_64, .macos }, 445 .{ .aarch64, .macos }, 446 }, 447 }); 448 449 cases.addCase(.{ 450 .params = params, 451 .target = target, 452 .name = "try return from within catch", 453 .source = 454 \\fn foo() !void { 455 \\ return error.TheSkyIsFalling; 456 \\} 457 \\ 458 \\fn bar() !void { 459 \\ return error.AndMyCarIsOutOfGas; 460 \\} 461 \\ 462 \\pub fn main() !void { 463 \\ foo() catch { // error trace should include foo() 464 \\ try bar(); 465 \\ }; 466 \\} 467 , 468 .expect_error = "AndMyCarIsOutOfGas", 469 .expect_trace = 470 \\source.zig:2:5: [address] in foo 471 \\ return error.TheSkyIsFalling; 472 \\ ^ 473 \\source.zig:6:5: [address] in bar 474 \\ return error.AndMyCarIsOutOfGas; 475 \\ ^ 476 \\source.zig:11:9: [address] in main 477 \\ try bar(); 478 \\ ^ 479 , 480 .disable_trace_optimized = &.{ 481 .{ .x86_64, .windows }, 482 .{ .x86, .windows }, 483 .{ .x86_64, .macos }, 484 .{ .aarch64, .macos }, 485 }, 486 }); 487 488 cases.addCase(.{ 489 .params = params, 490 .target = target, 491 .name = "try return from within if-else", 492 .source = 493 \\fn foo() !void { 494 \\ return error.TheSkyIsFalling; 495 \\} 496 \\ 497 \\fn bar() !void { 498 \\ return error.AndMyCarIsOutOfGas; 499 \\} 500 \\ 501 \\pub fn main() !void { 502 \\ if (foo()) |_| {} else |_| { // error trace should include foo() 503 \\ try bar(); 504 \\ } 505 \\} 506 , 507 .expect_error = "AndMyCarIsOutOfGas", 508 .expect_trace = 509 \\source.zig:2:5: [address] in foo 510 \\ return error.TheSkyIsFalling; 511 \\ ^ 512 \\source.zig:6:5: [address] in bar 513 \\ return error.AndMyCarIsOutOfGas; 514 \\ ^ 515 \\source.zig:11:9: [address] in main 516 \\ try bar(); 517 \\ ^ 518 , 519 .disable_trace_optimized = &.{ 520 .{ .x86_64, .windows }, 521 .{ .x86, .windows }, 522 .{ .x86_64, .macos }, 523 .{ .aarch64, .macos }, 524 }, 525 }); 526 527 cases.addCase(.{ 528 .params = params, 529 .target = target, 530 .name = "try try return return", 531 .source = 532 \\fn foo() !void { 533 \\ try bar(); 534 \\} 535 \\ 536 \\fn bar() !void { 537 \\ return make_error(); 538 \\} 539 \\ 540 \\fn make_error() !void { 541 \\ return error.TheSkyIsFalling; 542 \\} 543 \\ 544 \\pub fn main() !void { 545 \\ try foo(); 546 \\} 547 , 548 .expect_error = "TheSkyIsFalling", 549 .expect_trace = 550 \\source.zig:10:5: [address] in make_error 551 \\ return error.TheSkyIsFalling; 552 \\ ^ 553 \\source.zig:6:5: [address] in bar 554 \\ return make_error(); 555 \\ ^ 556 \\source.zig:2:5: [address] in foo 557 \\ try bar(); 558 \\ ^ 559 \\source.zig:14:5: [address] in main 560 \\ try foo(); 561 \\ ^ 562 , 563 .disable_trace_optimized = &.{ 564 .{ .x86_64, .windows }, 565 .{ .x86, .windows }, 566 .{ .x86_64, .macos }, 567 .{ .aarch64, .macos }, 568 }, 569 }); 570 571 cases.addCase(.{ 572 .params = params, 573 .target = target, 574 .name = "error union switch with call operand", 575 .source = 576 \\pub fn main() !void { 577 \\ try foo(); 578 \\ return error.TheSkyIsFalling; 579 \\} 580 \\ 581 \\noinline fn failure() error{ Fatal, NonFatal }!void { 582 \\ return error.NonFatal; 583 \\} 584 \\ 585 \\fn foo() error{Fatal}!void { 586 \\ return failure() catch |err| switch (err) { 587 \\ error.Fatal => return error.Fatal, 588 \\ error.NonFatal => return, 589 \\ }; 590 \\} 591 , 592 .expect_error = "TheSkyIsFalling", 593 .expect_trace = 594 \\source.zig:3:5: [address] in main 595 \\ return error.TheSkyIsFalling; 596 \\ ^ 597 , 598 .disable_trace_optimized = &.{ 599 .{ .x86_64, .freebsd }, 600 .{ .x86_64, .netbsd }, 601 .{ .x86_64, .linux }, 602 .{ .x86, .linux }, 603 .{ .aarch64, .freebsd }, 604 .{ .aarch64, .netbsd }, 605 .{ .aarch64, .linux }, 606 .{ .loongarch64, .linux }, 607 .{ .powerpc64le, .linux }, 608 .{ .riscv64, .linux }, 609 .{ .s390x, .linux }, 610 .{ .x86_64, .openbsd }, 611 .{ .x86_64, .windows }, 612 .{ .x86, .windows }, 613 .{ .x86_64, .macos }, 614 .{ .aarch64, .macos }, 615 }, 616 }); 617 618 cases.addCase(.{ 619 .params = params, 620 .target = target, 621 .name = "trace through inline call", 622 // The main function has two inline calls to ensure 623 // that inlinees in PDBs are properly deduplicated. 624 .source = 625 \\pub fn main() !void { 626 \\ try foo(false); 627 \\ try foo(true); 628 \\} 629 \\inline fn foo(b: bool) !void { 630 \\ if (b) try bar(); 631 \\} 632 \\fn bar() !void { 633 \\ return error.ThisIsSoSad; 634 \\} 635 , 636 .expect_error = "ThisIsSoSad", 637 .expect_trace = switch (target.os.tag) { 638 // LLVM doesn't emit column info in the binary annotations for inlinee callees in PDBs, 639 // so our expected result is slightly different for Windows than on other operating 640 // systems. 641 .windows => 642 \\source.zig:9:5: [address] in bar 643 \\ return error.ThisIsSoSad; 644 \\ ^ 645 \\source.zig:6: [address] in foo 646 \\ if (b) try bar(); 647 \\ 648 \\source.zig:3:5: [address] in main 649 \\ try foo(true); 650 \\ ^ 651 , 652 else => 653 \\source.zig:9:5: [address] in bar 654 \\ return error.ThisIsSoSad; 655 \\ ^ 656 \\source.zig:6:12: [address] in foo 657 \\ if (b) try bar(); 658 \\ ^ 659 \\source.zig:3:5: [address] in main 660 \\ try foo(true); 661 \\ ^ 662 , 663 }, 664 .disable_trace_optimized = &.{ 665 .{ .x86_64, .freebsd }, 666 .{ .x86_64, .netbsd }, 667 .{ .x86_64, .linux }, 668 .{ .x86, .linux }, 669 .{ .aarch64, .freebsd }, 670 .{ .aarch64, .netbsd }, 671 .{ .aarch64, .openbsd }, 672 .{ .aarch64, .linux }, 673 .{ .loongarch64, .linux }, 674 .{ .powerpc64le, .linux }, 675 .{ .riscv64, .linux }, 676 .{ .s390x, .linux }, 677 .{ .x86_64, .openbsd }, 678 .{ .x86_64, .windows }, 679 .{ .x86, .windows }, 680 .{ .x86_64, .macos }, 681 .{ .aarch64, .macos }, 682 }, 683 }); 684 } 685