authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-09-28 15:58:41-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-09-28 15:58:41-07:00
log0cdec976e4eaf96e1735ff417b222ab1463727e8
tree1b47bb75eb6f29f9da11c93ac7ea924a8bfb326a
parent085cc54aadb327b9910be2c72b31ea046e7e8f52
parent2857ca1edc1c3fa83298d2e8f6d505a3776f1ae3
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21520 from ziglang/no-formatted-panics

formalize the panic interface closes #17969 closes #20240

23 files changed, 734 insertions(+), 843 deletions(-)

lib/compiler_rt/common.zig+7-6
...@@ -75,13 +75,14 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {...@@ -75,13 +75,14 @@ pub const gnu_f16_abi = switch (builtin.cpu.arch) {
7575
76pub const want_sparc_abi = builtin.cpu.arch.isSPARC();76pub const want_sparc_abi = builtin.cpu.arch.isSPARC();
7777
78// Avoid dragging in the runtime safety mechanisms into this .o file,78// Avoid dragging in the runtime safety mechanisms into this .o file, unless
79// unless we're trying to test compiler-rt.79// we're trying to test compiler-rt.
80pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {80pub const Panic = if (builtin.is_test) std.debug.FormattedPanic else struct {};
81 _ = error_return_trace;81
82/// To be deleted after zig1.wasm is updated.
83pub fn panic(msg: []const u8, error_return_trace: ?*std.builtin.StackTrace, ret_addr: ?usize) noreturn {
82 if (builtin.is_test) {84 if (builtin.is_test) {
83 @branchHint(.cold);85 std.debug.defaultPanic(msg, error_return_trace, ret_addr orelse @returnAddress());
84 std.debug.panic("{s}", .{msg});
85 } else {86 } else {
86 unreachable;87 unreachable;
87 }88 }
lib/std/Thread.zig+77
...@@ -22,6 +22,83 @@ pub const WaitGroup = @import("Thread/WaitGroup.zig");...@@ -22,6 +22,83 @@ pub const WaitGroup = @import("Thread/WaitGroup.zig");
2222
23pub const use_pthreads = native_os != .windows and native_os != .wasi and builtin.link_libc;23pub const use_pthreads = native_os != .windows and native_os != .wasi and builtin.link_libc;
2424
25/// Spurious wakeups are possible and no precision of timing is guaranteed.
26pub fn sleep(nanoseconds: u64) void {
27 if (builtin.os.tag == .windows) {
28 const big_ms_from_ns = nanoseconds / std.time.ns_per_ms;
29 const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
30 windows.kernel32.Sleep(ms);
31 return;
32 }
33
34 if (builtin.os.tag == .wasi) {
35 const w = std.os.wasi;
36 const userdata: w.userdata_t = 0x0123_45678;
37 const clock: w.subscription_clock_t = .{
38 .id = .MONOTONIC,
39 .timeout = nanoseconds,
40 .precision = 0,
41 .flags = 0,
42 };
43 const in: w.subscription_t = .{
44 .userdata = userdata,
45 .u = .{
46 .tag = .CLOCK,
47 .u = .{ .clock = clock },
48 },
49 };
50
51 var event: w.event_t = undefined;
52 var nevents: usize = undefined;
53 _ = w.poll_oneoff(&in, &event, 1, &nevents);
54 return;
55 }
56
57 if (builtin.os.tag == .uefi) {
58 const boot_services = std.os.uefi.system_table.boot_services.?;
59 const us_from_ns = nanoseconds / std.time.ns_per_us;
60 const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
61 _ = boot_services.stall(us);
62 return;
63 }
64
65 const s = nanoseconds / std.time.ns_per_s;
66 const ns = nanoseconds % std.time.ns_per_s;
67
68 // Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
69 // since Linux 2.6 and glibc 2.1 anyway.
70 if (builtin.os.tag == .linux) {
71 const linux = std.os.linux;
72
73 var req: linux.timespec = .{
74 .sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
75 .nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
76 };
77 var rem: linux.timespec = undefined;
78
79 while (true) {
80 switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
81 .SUCCESS => return,
82 .INTR => {
83 req = rem;
84 continue;
85 },
86 .FAULT,
87 .INVAL,
88 .OPNOTSUPP,
89 => unreachable,
90 else => return,
91 }
92 }
93 }
94
95 posix.nanosleep(s, ns);
96}
97
98test sleep {
99 sleep(1);
100}
101
25const Thread = @This();102const Thread = @This();
26const Impl = if (native_os == .windows)103const Impl = if (native_os == .windows)
27 WindowsThreadImpl104 WindowsThreadImpl
lib/std/builtin.zig+42-183
...@@ -761,195 +761,54 @@ pub const TestFn = struct {...@@ -761,195 +761,54 @@ pub const TestFn = struct {
761 func: *const fn () anyerror!void,761 func: *const fn () anyerror!void,
762};762};
763763
764/// This function type is used by the Zig language code generation and764/// Deprecated, use the `Panic` namespace instead.
765/// therefore must be kept in sync with the compiler implementation.765/// To be deleted after 0.14.0 is released.
766pub const PanicFn = fn ([]const u8, ?*StackTrace, ?usize) noreturn;766pub const PanicFn = fn ([]const u8, ?*StackTrace, ?usize) noreturn;
767767/// Deprecated, use the `Panic` namespace instead.
768/// This function is used by the Zig language code generation and768/// To be deleted after 0.14.0 is released.
769/// therefore must be kept in sync with the compiler implementation.769pub const panic: PanicFn = Panic.call;
770pub const panic: PanicFn = if (@hasDecl(root, "panic"))770
771 root.panic771/// This namespace is used by the Zig compiler to emit various kinds of safety
772else if (@hasDecl(root, "os") and @hasDecl(root.os, "panic"))772/// panics. These can be overridden by making a public `Panic` namespace in the
773 root.os.panic773/// root source file.
774pub const Panic: type = if (@hasDecl(root, "Panic"))
775 root.Panic
776else if (@hasDecl(root, "panic")) // Deprecated, use `Panic` instead.
777 DeprecatedPanic
778else if (builtin.zig_backend == .stage2_riscv64)
779 std.debug.SimplePanic // https://github.com/ziglang/zig/issues/21519
774else780else
775 default_panic;781 std.debug.FormattedPanic;
776782
777/// This function is used by the Zig language code generation and783/// To be deleted after 0.14.0 is released.
778/// therefore must be kept in sync with the compiler implementation.784const DeprecatedPanic = struct {
779pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace, ret_addr: ?usize) noreturn {785 pub const call = root.panic;
780 @branchHint(.cold);786 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
781787 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
782 // For backends that cannot handle the language features depended on by the788 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
783 // default panic handler, we have a simpler panic handler:789 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
784 if (builtin.zig_backend == .stage2_wasm or790 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
785 builtin.zig_backend == .stage2_arm or791 pub const messages = std.debug.FormattedPanic.messages;
786 builtin.zig_backend == .stage2_aarch64 or792};
787 builtin.zig_backend == .stage2_x86 or793
788 (builtin.zig_backend == .stage2_x86_64 and (builtin.target.ofmt != .elf and builtin.target.ofmt != .macho)) or794/// To be deleted after zig1.wasm is updated.
789 builtin.zig_backend == .stage2_sparc64 or795pub const panicSentinelMismatch = Panic.sentinelMismatch;
790 builtin.zig_backend == .stage2_spirv64)796/// To be deleted after zig1.wasm is updated.
791 {797pub const panicUnwrapError = Panic.unwrapError;
792 while (true) {798/// To be deleted after zig1.wasm is updated.
793 @breakpoint();799pub const panicOutOfBounds = Panic.outOfBounds;
794 }800/// To be deleted after zig1.wasm is updated.
795 }801pub const panicStartGreaterThanEnd = Panic.startGreaterThanEnd;
796802/// To be deleted after zig1.wasm is updated.
797 if (builtin.zig_backend == .stage2_riscv64) {803pub const panicInactiveUnionField = Panic.inactiveUnionField;
798 std.debug.print("panic: {s}\n", .{msg});804/// To be deleted after zig1.wasm is updated.
799 @breakpoint();805pub const panic_messages = Panic.messages;
800 std.posix.exit(127);
801 }
802
803 switch (builtin.os.tag) {
804 .freestanding => {
805 while (true) {
806 @breakpoint();
807 }
808 },
809 .wasi => {
810 std.debug.print("{s}", .{msg});
811 std.posix.abort();
812 },
813 .uefi => {
814 const uefi = std.os.uefi;
815
816 const Formatter = struct {
817 pub fn fmt(exit_msg: []const u8, out: []u16) ![:0]u16 {
818 var u8_buf: [256]u8 = undefined;
819 const slice = try std.fmt.bufPrint(&u8_buf, "err: {s}\r\n", .{exit_msg});
820 // We pass len - 1 because we need to add a null terminator after
821 const len = try std.unicode.utf8ToUtf16Le(out[0 .. out.len - 1], slice);
822
823 out[len] = 0;
824
825 return out[0..len :0];
826 }
827 };
828
829 const ExitData = struct {
830 pub fn create_exit_data(exit_msg: [:0]u16, exit_size: *usize) ![*:0]u16 {
831 // Need boot services for pool allocation
832 if (uefi.system_table.boot_services == null) {
833 return error.BootServicesUnavailable;
834 }
835
836 // ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220)
837 const exit_data: []u16 = try uefi.raw_pool_allocator.alloc(u16, exit_msg.len + 1);
838
839 @memcpy(exit_data[0 .. exit_msg.len + 1], exit_msg[0 .. exit_msg.len + 1]);
840 exit_size.* = exit_msg.len + 1;
841
842 return @as([*:0]u16, @ptrCast(exit_data.ptr));
843 }
844 };
845
846 var buf: [256]u16 = undefined;
847 const utf16 = Formatter.fmt(msg, &buf) catch null;
848
849 var exit_size: usize = 0;
850 const exit_data = if (utf16) |u|
851 ExitData.create_exit_data(u, &exit_size) catch null
852 else
853 null;
854
855 if (utf16) |str| {
856 // Output to both std_err and con_out, as std_err is easier
857 // to read in stuff like QEMU at times, but, unlike con_out,
858 // isn't visible on actual hardware if directly booted into
859 inline for ([_]?*uefi.protocol.SimpleTextOutput{ uefi.system_table.std_err, uefi.system_table.con_out }) |o| {
860 if (o) |out| {
861 _ = out.setAttribute(uefi.protocol.SimpleTextOutput.red);
862 _ = out.outputString(str);
863 _ = out.setAttribute(uefi.protocol.SimpleTextOutput.white);
864 }
865 }
866 }
867
868 if (uefi.system_table.boot_services) |bs| {
869 _ = bs.exit(uefi.handle, .Aborted, exit_size, exit_data);
870 }
871
872 // Didn't have boot_services, just fallback to whatever.
873 std.posix.abort();
874 },
875 .cuda, .amdhsa => std.posix.abort(),
876 .plan9 => {
877 var status: [std.os.plan9.ERRMAX]u8 = undefined;
878 const len = @min(msg.len, status.len - 1);
879 @memcpy(status[0..len], msg[0..len]);
880 status[len] = 0;
881 std.os.plan9.exits(status[0..len :0]);
882 },
883 else => {
884 const first_trace_addr = ret_addr orelse @returnAddress();
885 std.debug.panicImpl(error_return_trace, first_trace_addr, msg);
886 },
887 }
888}
889
890pub fn panicSentinelMismatch(expected: anytype, actual: @TypeOf(expected)) noreturn {
891 @branchHint(.cold);
892 std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{ expected, actual });
893}
894
895pub fn panicUnwrapError(st: ?*StackTrace, err: anyerror) noreturn {
896 @branchHint(.cold);
897 std.debug.panicExtra(st, @returnAddress(), "attempt to unwrap error: {s}", .{@errorName(err)});
898}
899
900pub fn panicOutOfBounds(index: usize, len: usize) noreturn {
901 @branchHint(.cold);
902 std.debug.panicExtra(null, @returnAddress(), "index out of bounds: index {d}, len {d}", .{ index, len });
903}
904
905pub fn panicStartGreaterThanEnd(start: usize, end: usize) noreturn {
906 @branchHint(.cold);
907 std.debug.panicExtra(null, @returnAddress(), "start index {d} is larger than end index {d}", .{ start, end });
908}
909
910pub fn panicInactiveUnionField(active: anytype, wanted: @TypeOf(active)) noreturn {
911 @branchHint(.cold);
912 std.debug.panicExtra(null, @returnAddress(), "access of union field '{s}' while field '{s}' is active", .{ @tagName(wanted), @tagName(active) });
913}
914
915pub const panic_messages = struct {
916 pub const unreach = "reached unreachable code";
917 pub const unwrap_null = "attempt to use null value";
918 pub const cast_to_null = "cast causes pointer to be null";
919 pub const incorrect_alignment = "incorrect alignment";
920 pub const invalid_error_code = "invalid error code";
921 pub const cast_truncated_data = "integer cast truncated bits";
922 pub const negative_to_unsigned = "attempt to cast negative value to unsigned integer";
923 pub const integer_overflow = "integer overflow";
924 pub const shl_overflow = "left shift overflowed bits";
925 pub const shr_overflow = "right shift overflowed bits";
926 pub const divide_by_zero = "division by zero";
927 pub const exact_division_remainder = "exact division produced remainder";
928 pub const inactive_union_field = "access of inactive union field";
929 pub const integer_part_out_of_bounds = "integer part of floating point value out of bounds";
930 pub const corrupt_switch = "switch on corrupt value";
931 pub const shift_rhs_too_big = "shift amount is greater than the type size";
932 pub const invalid_enum_value = "invalid enum value";
933 pub const sentinel_mismatch = "sentinel mismatch";
934 pub const unwrap_error = "attempt to unwrap error";
935 pub const index_out_of_bounds = "index out of bounds";
936 pub const start_index_greater_than_end = "start index is larger than end index";
937 pub const for_len_mismatch = "for loop over objects with non-equal lengths";
938 pub const memcpy_len_mismatch = "@memcpy arguments have non-equal lengths";
939 pub const memcpy_alias = "@memcpy arguments alias";
940 pub const noreturn_returned = "'noreturn' function returned";
941};
942806
943pub noinline fn returnError(st: *StackTrace) void {807pub noinline fn returnError(st: *StackTrace) void {
944 @branchHint(.cold);808 @branchHint(.unlikely);
945 @setRuntimeSafety(false);809 @setRuntimeSafety(false);
946 addErrRetTraceAddr(st, @returnAddress());
947}
948
949pub inline fn addErrRetTraceAddr(st: *StackTrace, addr: usize) void {
950 if (st.index < st.instruction_addresses.len)810 if (st.index < st.instruction_addresses.len)
951 st.instruction_addresses[st.index] = addr;811 st.instruction_addresses[st.index] = @returnAddress();
952
953 st.index += 1;812 st.index += 1;
954}813}
955814
lib/std/debug.zig+107-60
...@@ -21,6 +21,9 @@ pub const SelfInfo = @import("debug/SelfInfo.zig");...@@ -21,6 +21,9 @@ pub const SelfInfo = @import("debug/SelfInfo.zig");
21pub const Info = @import("debug/Info.zig");21pub const Info = @import("debug/Info.zig");
22pub const Coverage = @import("debug/Coverage.zig");22pub const Coverage = @import("debug/Coverage.zig");
2323
24pub const FormattedPanic = @import("debug/FormattedPanic.zig");
25pub const SimplePanic = @import("debug/SimplePanic.zig");
26
24/// Unresolved source locations can be represented with a single `usize` that27/// Unresolved source locations can be represented with a single `usize` that
25/// corresponds to a virtual memory address of the program counter. Combined28/// corresponds to a virtual memory address of the program counter. Combined
26/// with debug information, those values can be converted into a resolved29/// with debug information, those values can be converted into a resolved
...@@ -408,14 +411,21 @@ pub fn assertReadable(slice: []const volatile u8) void {...@@ -408,14 +411,21 @@ pub fn assertReadable(slice: []const volatile u8) void {
408 for (slice) |*byte| _ = byte.*;411 for (slice) |*byte| _ = byte.*;
409}412}
410413
414/// By including a call to this function, the caller gains an error return trace
415/// secret parameter, making `@errorReturnTrace()` more useful. This is not
416/// necessary if the function already contains a call to an errorable function
417/// elsewhere.
418pub fn errorReturnTraceHelper() anyerror!void {}
419
420/// Equivalent to `@panic` but with a formatted message.
411pub fn panic(comptime format: []const u8, args: anytype) noreturn {421pub fn panic(comptime format: []const u8, args: anytype) noreturn {
412 @branchHint(.cold);422 @branchHint(.cold);
413423 errorReturnTraceHelper() catch unreachable;
414 panicExtra(@errorReturnTrace(), @returnAddress(), format, args);424 panicExtra(@errorReturnTrace(), @returnAddress(), format, args);
415}425}
416426
417/// `panicExtra` is useful when you want to print out an `@errorReturnTrace`427/// Equivalent to `@panic` but with a formatted message, and with an explicitly
418/// and also print out some values.428/// provided `@errorReturnTrace` and return address.
419pub fn panicExtra(429pub fn panicExtra(
420 trace: ?*std.builtin.StackTrace,430 trace: ?*std.builtin.StackTrace,
421 ret_addr: ?usize,431 ret_addr: ?usize,
...@@ -436,7 +446,7 @@ pub fn panicExtra(...@@ -436,7 +446,7 @@ pub fn panicExtra(
436 break :blk &buf;446 break :blk &buf;
437 },447 },
438 };448 };
439 std.builtin.panic(msg, trace, ret_addr);449 std.builtin.Panic.call(msg, trace, ret_addr);
440}450}
441451
442/// Non-zero whenever the program triggered a panic.452/// Non-zero whenever the program triggered a panic.
...@@ -447,11 +457,70 @@ var panicking = std.atomic.Value(u8).init(0);...@@ -447,11 +457,70 @@ var panicking = std.atomic.Value(u8).init(0);
447/// This is used to catch and handle panics triggered by the panic handler.457/// This is used to catch and handle panics triggered by the panic handler.
448threadlocal var panic_stage: usize = 0;458threadlocal var panic_stage: usize = 0;
449459
450// `panicImpl` could be useful in implementing a custom panic handler which460/// Dumps a stack trace to standard error, then aborts.
451// calls the default handler (on supported platforms)461pub fn defaultPanic(
452pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize, msg: []const u8) noreturn {462 msg: []const u8,
463 error_return_trace: ?*const std.builtin.StackTrace,
464 first_trace_addr: ?usize,
465) noreturn {
453 @branchHint(.cold);466 @branchHint(.cold);
454467
468 // For backends that cannot handle the language features depended on by the
469 // default panic handler, we have a simpler panic handler:
470 if (builtin.zig_backend == .stage2_wasm or
471 builtin.zig_backend == .stage2_arm or
472 builtin.zig_backend == .stage2_aarch64 or
473 builtin.zig_backend == .stage2_x86 or
474 (builtin.zig_backend == .stage2_x86_64 and (builtin.target.ofmt != .elf and builtin.target.ofmt != .macho)) or
475 builtin.zig_backend == .stage2_sparc64 or
476 builtin.zig_backend == .stage2_spirv64)
477 {
478 @trap();
479 }
480
481 switch (builtin.os.tag) {
482 .freestanding => {
483 @trap();
484 },
485 .uefi => {
486 const uefi = std.os.uefi;
487
488 var utf16_buffer: [1000]u16 = undefined;
489 const len_minus_3 = std.unicode.utf8ToUtf16Le(&utf16_buffer, msg) catch 0;
490 utf16_buffer[len_minus_3][0..3].* = .{ '\r', '\n', 0 };
491 const len = len_minus_3 + 3;
492 const exit_msg = utf16_buffer[0 .. len - 1 :0];
493
494 // Output to both std_err and con_out, as std_err is easier
495 // to read in stuff like QEMU at times, but, unlike con_out,
496 // isn't visible on actual hardware if directly booted into
497 inline for ([_]?*uefi.protocol.SimpleTextOutput{ uefi.system_table.std_err, uefi.system_table.con_out }) |o| {
498 if (o) |out| {
499 _ = out.setAttribute(uefi.protocol.SimpleTextOutput.red);
500 _ = out.outputString(exit_msg);
501 _ = out.setAttribute(uefi.protocol.SimpleTextOutput.white);
502 }
503 }
504
505 if (uefi.system_table.boot_services) |bs| {
506 // ExitData buffer must be allocated using boot_services.allocatePool (spec: page 220)
507 const exit_data: []u16 = uefi.raw_pool_allocator.alloc(u16, exit_msg.len + 1) catch @trap();
508 @memcpy(exit_data, exit_msg[0..exit_data.len]); // Includes null terminator.
509 _ = bs.exit(uefi.handle, .Aborted, exit_msg.len + 1, exit_data);
510 }
511 @trap();
512 },
513 .cuda, .amdhsa => std.posix.abort(),
514 .plan9 => {
515 var status: [std.os.plan9.ERRMAX]u8 = undefined;
516 const len = @min(msg.len, status.len - 1);
517 @memcpy(status[0..len], msg[0..len]);
518 status[len] = 0;
519 std.os.plan9.exits(status[0..len :0]);
520 },
521 else => {},
522 }
523
455 if (enable_segfault_handler) {524 if (enable_segfault_handler) {
456 // If a segfault happens while panicking, we want it to actually segfault, not trigger525 // If a segfault happens while panicking, we want it to actually segfault, not trigger
457 // the handler.526 // the handler.
...@@ -465,7 +534,6 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize...@@ -465,7 +534,6 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
465534
466 _ = panicking.fetchAdd(1, .seq_cst);535 _ = panicking.fetchAdd(1, .seq_cst);
467536
468 // Make sure to release the mutex when done
469 {537 {
470 lockStdErr();538 lockStdErr();
471 defer unlockStdErr();539 defer unlockStdErr();
...@@ -478,10 +546,9 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize...@@ -478,10 +546,9 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
478 stderr.print("thread {} panic: ", .{current_thread_id}) catch posix.abort();546 stderr.print("thread {} panic: ", .{current_thread_id}) catch posix.abort();
479 }547 }
480 stderr.print("{s}\n", .{msg}) catch posix.abort();548 stderr.print("{s}\n", .{msg}) catch posix.abort();
481 if (trace) |t| {549
482 dumpStackTrace(t.*);550 if (error_return_trace) |t| dumpStackTrace(t.*);
483 }551 dumpCurrentStackTrace(first_trace_addr orelse @returnAddress());
484 dumpCurrentStackTrace(first_trace_addr);
485 }552 }
486553
487 waitForOtherThreadToFinishPanicking();554 waitForOtherThreadToFinishPanicking();
...@@ -489,15 +556,12 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize...@@ -489,15 +556,12 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
489 1 => {556 1 => {
490 panic_stage = 2;557 panic_stage = 2;
491558
492 // A panic happened while trying to print a previous panic message,559 // A panic happened while trying to print a previous panic message.
493 // we're still holding the mutex but that's fine as we're going to560 // We're still holding the mutex but that's fine as we're going to
494 // call abort()561 // call abort().
495 const stderr = io.getStdErr().writer();562 io.getStdErr().writeAll("aborting due to recursive panic\n") catch {};
496 stderr.print("Panicked during a panic. Aborting.\n", .{}) catch posix.abort();
497 },
498 else => {
499 // Panicked while printing "Panicked during a panic."
500 },563 },
564 else => {}, // Panicked while printing the recursive panic message.
501 };565 };
502566
503 posix.abort();567 posix.abort();
...@@ -1157,7 +1221,7 @@ pub const default_enable_segfault_handler = runtime_safety and have_segfault_han...@@ -1157,7 +1221,7 @@ pub const default_enable_segfault_handler = runtime_safety and have_segfault_han
11571221
1158pub fn maybeEnableSegfaultHandler() void {1222pub fn maybeEnableSegfaultHandler() void {
1159 if (enable_segfault_handler) {1223 if (enable_segfault_handler) {
1160 std.debug.attachSegfaultHandler();1224 attachSegfaultHandler();
1161 }1225 }
1162}1226}
11631227
...@@ -1289,46 +1353,29 @@ fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(windows.WIN...@@ -1289,46 +1353,29 @@ fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(windows.WIN
1289 }1353 }
1290}1354}
12911355
1292fn handleSegfaultWindowsExtra(1356fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8) noreturn {
1293 info: *windows.EXCEPTION_POINTERS,1357 comptime assert(windows.CONTEXT != void);
1294 msg: u8,1358 nosuspend switch (panic_stage) {
1295 label: ?[]const u8,1359 0 => {
1296) noreturn {1360 panic_stage = 1;
1297 const exception_address = @intFromPtr(info.ExceptionRecord.ExceptionAddress);1361 _ = panicking.fetchAdd(1, .seq_cst);
1298 if (windows.CONTEXT != void) {1362
1299 nosuspend switch (panic_stage) {1363 {
1300 0 => {1364 lockStdErr();
1301 panic_stage = 1;1365 defer unlockStdErr();
1302 _ = panicking.fetchAdd(1, .seq_cst);
1303
1304 {
1305 lockStdErr();
1306 defer unlockStdErr();
1307
1308 dumpSegfaultInfoWindows(info, msg, label);
1309 }
13101366
1311 waitForOtherThreadToFinishPanicking();
1312 },
1313 else => {
1314 // panic mutex already locked
1315 dumpSegfaultInfoWindows(info, msg, label);1367 dumpSegfaultInfoWindows(info, msg, label);
1316 },1368 }
1317 };1369
1318 posix.abort();1370 waitForOtherThreadToFinishPanicking();
1319 } else {1371 },
1320 switch (msg) {1372 1 => {
1321 0 => panicImpl(null, exception_address, "{s}", label.?),1373 panic_stage = 2;
1322 1 => {1374 io.getStdErr().writeAll("aborting due to recursive panic\n") catch {};
1323 const format_item = "Segmentation fault at address 0x{x}";1375 },
1324 var buf: [format_item.len + 64]u8 = undefined; // 64 is arbitrary, but sufficiently large1376 else => {},
1325 const to_print = std.fmt.bufPrint(buf[0..buf.len], format_item, .{info.ExceptionRecord.ExceptionInformation[1]}) catch unreachable;1377 };
1326 panicImpl(null, exception_address, to_print);1378 posix.abort();
1327 },
1328 2 => panicImpl(null, exception_address, "Illegal Instruction"),
1329 else => unreachable,
1330 }
1331 }
1332}1379}
13331380
1334fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8) void {1381fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[]const u8) void {
...@@ -1347,7 +1394,7 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {...@@ -1347,7 +1394,7 @@ pub fn dumpStackPointerAddr(prefix: []const u8) void {
1347 const sp = asm (""1394 const sp = asm (""
1348 : [argc] "={rsp}" (-> usize),1395 : [argc] "={rsp}" (-> usize),
1349 );1396 );
1350 std.debug.print("{s} sp = 0x{x}\n", .{ prefix, sp });1397 print("{s} sp = 0x{x}\n", .{ prefix, sp });
1351}1398}
13521399
1353test "manage resources correctly" {1400test "manage resources correctly" {
lib/std/debug/FormattedPanic.zig created+45
...@@ -0,0 +1,45 @@
1//! This namespace is the default one used by the Zig compiler to emit various
2//! kinds of safety panics, due to the logic in `std.builtin.Panic`.
3//!
4//! Since Zig does not have interfaces, this file serves as an example template
5//! for users to provide their own alternative panic handling.
6//!
7//! As an alternative, see `std.debug.SimplePanic`.
8
9const std = @import("../std.zig");
10
11/// Dumps a stack trace to standard error, then aborts.
12///
13/// Explicit calls to `@panic` lower to calling this function.
14pub const call: fn ([]const u8, ?*std.builtin.StackTrace, ?usize) noreturn = std.debug.defaultPanic;
15
16pub fn sentinelMismatch(expected: anytype, found: @TypeOf(expected)) noreturn {
17 @branchHint(.cold);
18 std.debug.panicExtra(null, @returnAddress(), "sentinel mismatch: expected {any}, found {any}", .{
19 expected, found,
20 });
21}
22
23pub fn unwrapError(ert: ?*std.builtin.StackTrace, err: anyerror) noreturn {
24 @branchHint(.cold);
25 std.debug.panicExtra(ert, @returnAddress(), "attempt to unwrap error: {s}", .{@errorName(err)});
26}
27
28pub fn outOfBounds(index: usize, len: usize) noreturn {
29 @branchHint(.cold);
30 std.debug.panicExtra(null, @returnAddress(), "index out of bounds: index {d}, len {d}", .{ index, len });
31}
32
33pub fn startGreaterThanEnd(start: usize, end: usize) noreturn {
34 @branchHint(.cold);
35 std.debug.panicExtra(null, @returnAddress(), "start index {d} is larger than end index {d}", .{ start, end });
36}
37
38pub fn inactiveUnionField(active: anytype, accessed: @TypeOf(active)) noreturn {
39 @branchHint(.cold);
40 std.debug.panicExtra(null, @returnAddress(), "access of union field '{s}' while field '{s}' is active", .{
41 @tagName(accessed), @tagName(active),
42 });
43}
44
45pub const messages = std.debug.SimplePanic.messages;
lib/std/debug/SimplePanic.zig created+86
...@@ -0,0 +1,86 @@
1//! This namespace is the default one used by the Zig compiler to emit various
2//! kinds of safety panics, due to the logic in `std.builtin.Panic`.
3//!
4//! Since Zig does not have interfaces, this file serves as an example template
5//! for users to provide their own alternative panic handling.
6//!
7//! As an alternative, see `std.debug.FormattedPanic`.
8
9const std = @import("../std.zig");
10
11/// Prints the message to stderr without a newline and then traps.
12///
13/// Explicit calls to `@panic` lower to calling this function.
14pub fn call(msg: []const u8, ert: ?*std.builtin.StackTrace, ra: ?usize) noreturn {
15 @branchHint(.cold);
16 _ = ert;
17 _ = ra;
18 std.debug.lockStdErr();
19 const stderr = std.io.getStdErr();
20 stderr.writeAll(msg) catch {};
21 @trap();
22}
23
24pub fn sentinelMismatch(expected: anytype, found: @TypeOf(expected)) noreturn {
25 _ = found;
26 call("sentinel mismatch", null, null);
27}
28
29pub fn unwrapError(ert: ?*std.builtin.StackTrace, err: anyerror) noreturn {
30 _ = ert;
31 _ = &err;
32 call("attempt to unwrap error", null, null);
33}
34
35pub fn outOfBounds(index: usize, len: usize) noreturn {
36 _ = index;
37 _ = len;
38 call("index out of bounds", null, null);
39}
40
41pub fn startGreaterThanEnd(start: usize, end: usize) noreturn {
42 _ = start;
43 _ = end;
44 call("start index is larger than end index", null, null);
45}
46
47pub fn inactiveUnionField(active: anytype, accessed: @TypeOf(active)) noreturn {
48 _ = accessed;
49 call("access of inactive union field", null, null);
50}
51
52pub const messages = struct {
53 pub const reached_unreachable = "reached unreachable code";
54 pub const unwrap_null = "attempt to use null value";
55 pub const cast_to_null = "cast causes pointer to be null";
56 pub const incorrect_alignment = "incorrect alignment";
57 pub const invalid_error_code = "invalid error code";
58 pub const cast_truncated_data = "integer cast truncated bits";
59 pub const negative_to_unsigned = "attempt to cast negative value to unsigned integer";
60 pub const integer_overflow = "integer overflow";
61 pub const shl_overflow = "left shift overflowed bits";
62 pub const shr_overflow = "right shift overflowed bits";
63 pub const divide_by_zero = "division by zero";
64 pub const exact_division_remainder = "exact division produced remainder";
65 pub const integer_part_out_of_bounds = "integer part of floating point value out of bounds";
66 pub const corrupt_switch = "switch on corrupt value";
67 pub const shift_rhs_too_big = "shift amount is greater than the type size";
68 pub const invalid_enum_value = "invalid enum value";
69 pub const for_len_mismatch = "for loop over objects with non-equal lengths";
70 pub const memcpy_len_mismatch = "@memcpy arguments have non-equal lengths";
71 pub const memcpy_alias = "@memcpy arguments alias";
72 pub const noreturn_returned = "'noreturn' function returned";
73
74 /// To be deleted after zig1.wasm is updated.
75 pub const inactive_union_field = "access of inactive union field";
76 /// To be deleted after zig1.wasm is updated.
77 pub const sentinel_mismatch = "sentinel mismatch";
78 /// To be deleted after zig1.wasm is updated.
79 pub const unwrap_error = "attempt to unwrap error";
80 /// To be deleted after zig1.wasm is updated.
81 pub const index_out_of_bounds = "index out of bounds";
82 /// To be deleted after zig1.wasm is updated.
83 pub const start_index_greater_than_end = "start index is larger than end index";
84 /// To be deleted after zig1.wasm is updated.
85 pub const unreach = reached_unreachable;
86};
lib/std/fmt.zig+4-8
...@@ -1197,7 +1197,7 @@ pub fn formatInt(...@@ -1197,7 +1197,7 @@ pub fn formatInt(
1197 if (base == 10) {1197 if (base == 10) {
1198 while (a >= 100) : (a = @divTrunc(a, 100)) {1198 while (a >= 100) : (a = @divTrunc(a, 100)) {
1199 index -= 2;1199 index -= 2;
1200 buf[index..][0..2].* = digits2(@as(usize, @intCast(a % 100)));1200 buf[index..][0..2].* = digits2(@intCast(a % 100));
1201 }1201 }
12021202
1203 if (a < 10) {1203 if (a < 10) {
...@@ -1205,13 +1205,13 @@ pub fn formatInt(...@@ -1205,13 +1205,13 @@ pub fn formatInt(
1205 buf[index] = '0' + @as(u8, @intCast(a));1205 buf[index] = '0' + @as(u8, @intCast(a));
1206 } else {1206 } else {
1207 index -= 2;1207 index -= 2;
1208 buf[index..][0..2].* = digits2(@as(usize, @intCast(a)));1208 buf[index..][0..2].* = digits2(@intCast(a));
1209 }1209 }
1210 } else {1210 } else {
1211 while (true) {1211 while (true) {
1212 const digit = a % base;1212 const digit = a % base;
1213 index -= 1;1213 index -= 1;
1214 buf[index] = digitToChar(@as(u8, @intCast(digit)), case);1214 buf[index] = digitToChar(@intCast(digit), case);
1215 a /= base;1215 a /= base;
1216 if (a == 0) break;1216 if (a == 0) break;
1217 }1217 }
...@@ -1242,11 +1242,7 @@ pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options...@@ -1242,11 +1242,7 @@ pub fn formatIntBuf(out_buf: []u8, value: anytype, base: u8, case: Case, options
12421242
1243// Converts values in the range [0, 100) to a string.1243// Converts values in the range [0, 100) to a string.
1244pub fn digits2(value: usize) [2]u8 {1244pub fn digits2(value: usize) [2]u8 {
1245 return ("0001020304050607080910111213141516171819" ++1245 return "00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"[value * 2 ..][0..2].*;
1246 "2021222324252627282930313233343536373839" ++
1247 "4041424344454647484950515253545556575859" ++
1248 "6061626364656667686970717273747576777879" ++
1249 "8081828384858687888990919293949596979899")[value * 2 ..][0..2].*;
1250}1246}
12511247
1252const FormatDurationData = struct {1248const FormatDurationData = struct {
lib/std/time.zig+4-78
...@@ -8,82 +8,8 @@ const posix = std.posix;...@@ -8,82 +8,8 @@ const posix = std.posix;
88
9pub const epoch = @import("time/epoch.zig");9pub const epoch = @import("time/epoch.zig");
1010
11/// Spurious wakeups are possible and no precision of timing is guaranteed.11/// Deprecated: moved to std.Thread.sleep
12pub fn sleep(nanoseconds: u64) void {12pub const sleep = std.Thread.sleep;
13 if (builtin.os.tag == .windows) {
14 const big_ms_from_ns = nanoseconds / ns_per_ms;
15 const ms = math.cast(windows.DWORD, big_ms_from_ns) orelse math.maxInt(windows.DWORD);
16 windows.kernel32.Sleep(ms);
17 return;
18 }
19
20 if (builtin.os.tag == .wasi) {
21 const w = std.os.wasi;
22 const userdata: w.userdata_t = 0x0123_45678;
23 const clock: w.subscription_clock_t = .{
24 .id = .MONOTONIC,
25 .timeout = nanoseconds,
26 .precision = 0,
27 .flags = 0,
28 };
29 const in: w.subscription_t = .{
30 .userdata = userdata,
31 .u = .{
32 .tag = .CLOCK,
33 .u = .{ .clock = clock },
34 },
35 };
36
37 var event: w.event_t = undefined;
38 var nevents: usize = undefined;
39 _ = w.poll_oneoff(&in, &event, 1, &nevents);
40 return;
41 }
42
43 if (builtin.os.tag == .uefi) {
44 const boot_services = std.os.uefi.system_table.boot_services.?;
45 const us_from_ns = nanoseconds / ns_per_us;
46 const us = math.cast(usize, us_from_ns) orelse math.maxInt(usize);
47 _ = boot_services.stall(us);
48 return;
49 }
50
51 const s = nanoseconds / ns_per_s;
52 const ns = nanoseconds % ns_per_s;
53
54 // Newer kernel ports don't have old `nanosleep()` and `clock_nanosleep()` has been around
55 // since Linux 2.6 and glibc 2.1 anyway.
56 if (builtin.os.tag == .linux) {
57 const linux = std.os.linux;
58
59 var req: linux.timespec = .{
60 .sec = std.math.cast(linux.time_t, s) orelse std.math.maxInt(linux.time_t),
61 .nsec = std.math.cast(linux.time_t, ns) orelse std.math.maxInt(linux.time_t),
62 };
63 var rem: linux.timespec = undefined;
64
65 while (true) {
66 switch (linux.E.init(linux.clock_nanosleep(.MONOTONIC, .{ .ABSTIME = false }, &req, &rem))) {
67 .SUCCESS => return,
68 .INTR => {
69 req = rem;
70 continue;
71 },
72 .FAULT,
73 .INVAL,
74 .OPNOTSUPP,
75 => unreachable,
76 else => return,
77 }
78 }
79 }
80
81 posix.nanosleep(s, ns);
82}
83
84test sleep {
85 sleep(1);
86}
8713
88/// Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.14/// Get a calendar timestamp, in seconds, relative to UTC 1970-01-01.
89/// Precision of timing depends on the hardware and operating system.15/// Precision of timing depends on the hardware and operating system.
...@@ -155,7 +81,7 @@ test milliTimestamp {...@@ -155,7 +81,7 @@ test milliTimestamp {
155 const margin = ns_per_ms * 50;81 const margin = ns_per_ms * 50;
15682
157 const time_0 = milliTimestamp();83 const time_0 = milliTimestamp();
158 sleep(ns_per_ms);84 std.Thread.sleep(ns_per_ms);
159 const time_1 = milliTimestamp();85 const time_1 = milliTimestamp();
160 const interval = time_1 - time_0;86 const interval = time_1 - time_0;
161 try testing.expect(interval > 0);87 try testing.expect(interval > 0);
...@@ -359,7 +285,7 @@ test Timer {...@@ -359,7 +285,7 @@ test Timer {
359 const margin = ns_per_ms * 150;285 const margin = ns_per_ms * 150;
360286
361 var timer = try Timer.start();287 var timer = try Timer.start();
362 sleep(10 * ns_per_ms);288 std.Thread.sleep(10 * ns_per_ms);
363 const time_0 = timer.read();289 const time_0 = timer.read();
364 try testing.expect(time_0 > 0);290 try testing.expect(time_0 > 0);
365 // Tests should not depend on timings: skip test if outside margin.291 // Tests should not depend on timings: skip test if outside margin.
src/Compilation.zig-8
...@@ -195,7 +195,6 @@ job_queued_compiler_rt_obj: bool = false,...@@ -195,7 +195,6 @@ job_queued_compiler_rt_obj: bool = false,
195job_queued_fuzzer_lib: bool = false,195job_queued_fuzzer_lib: bool = false,
196job_queued_update_builtin_zig: bool,196job_queued_update_builtin_zig: bool,
197alloc_failure_occurred: bool = false,197alloc_failure_occurred: bool = false,
198formatted_panics: bool = false,
199last_update_was_cache_hit: bool = false,198last_update_was_cache_hit: bool = false,
200199
201c_source_files: []const CSourceFile,200c_source_files: []const CSourceFile,
...@@ -1088,7 +1087,6 @@ pub const CreateOptions = struct {...@@ -1088,7 +1087,6 @@ pub const CreateOptions = struct {
1088 /// executable this field is ignored.1087 /// executable this field is ignored.
1089 want_compiler_rt: ?bool = null,1088 want_compiler_rt: ?bool = null,
1090 want_lto: ?bool = null,1089 want_lto: ?bool = null,
1091 formatted_panics: ?bool = null,
1092 function_sections: bool = false,1090 function_sections: bool = false,
1093 data_sections: bool = false,1091 data_sections: bool = false,
1094 no_builtin: bool = false,1092 no_builtin: bool = false,
...@@ -1357,9 +1355,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1357,9 +1355,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1357 }1355 }
1358 }1356 }
13591357
1360 // TODO: https://github.com/ziglang/zig/issues/17969
1361 const formatted_panics = options.formatted_panics orelse (options.root_mod.optimize_mode == .Debug);
1362
1363 const error_limit = options.error_limit orelse (std.math.maxInt(u16) - 1);1358 const error_limit = options.error_limit orelse (std.math.maxInt(u16) - 1);
13641359
1365 // We put everything into the cache hash that *cannot be modified1360 // We put everything into the cache hash that *cannot be modified
...@@ -1520,7 +1515,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1520,7 +1515,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1520 .verbose_link = options.verbose_link,1515 .verbose_link = options.verbose_link,
1521 .disable_c_depfile = options.disable_c_depfile,1516 .disable_c_depfile = options.disable_c_depfile,
1522 .reference_trace = options.reference_trace,1517 .reference_trace = options.reference_trace,
1523 .formatted_panics = formatted_panics,
1524 .time_report = options.time_report,1518 .time_report = options.time_report,
1525 .stack_report = options.stack_report,1519 .stack_report = options.stack_report,
1526 .test_filters = options.test_filters,1520 .test_filters = options.test_filters,
...@@ -1638,7 +1632,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil...@@ -1638,7 +1632,6 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
1638 hash.addListOfBytes(options.test_filters);1632 hash.addListOfBytes(options.test_filters);
1639 hash.addOptionalBytes(options.test_name_prefix);1633 hash.addOptionalBytes(options.test_name_prefix);
1640 hash.add(options.skip_linker_dependencies);1634 hash.add(options.skip_linker_dependencies);
1641 hash.add(formatted_panics);
1642 hash.add(options.emit_h != null);1635 hash.add(options.emit_h != null);
1643 hash.add(error_limit);1636 hash.add(error_limit);
16441637
...@@ -2564,7 +2557,6 @@ fn addNonIncrementalStuffToCacheManifest(...@@ -2564,7 +2557,6 @@ fn addNonIncrementalStuffToCacheManifest(
2564 man.hash.addListOfBytes(comp.test_filters);2557 man.hash.addListOfBytes(comp.test_filters);
2565 man.hash.addOptionalBytes(comp.test_name_prefix);2558 man.hash.addOptionalBytes(comp.test_name_prefix);
2566 man.hash.add(comp.skip_linker_dependencies);2559 man.hash.add(comp.skip_linker_dependencies);
2567 man.hash.add(comp.formatted_panics);
2568 //man.hash.add(mod.emit_h != null);2560 //man.hash.add(mod.emit_h != null);
2569 man.hash.add(mod.error_limit);2561 man.hash.add(mod.error_limit);
2570 } else {2562 } else {
src/InternPool.zig+25-9
...@@ -7353,6 +7353,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7353,6 +7353,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7353 .func_type => unreachable, // use getFuncType() instead7353 .func_type => unreachable, // use getFuncType() instead
7354 .@"extern" => unreachable, // use getExtern() instead7354 .@"extern" => unreachable, // use getExtern() instead
7355 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead7355 .func => unreachable, // use getFuncInstance() or getFuncDecl() instead
7356 .un => unreachable, // use getUnion instead
73567357
7357 .variable => |variable| {7358 .variable => |variable| {
7358 const has_init = variable.init != .none;7359 const has_init = variable.init != .none;
...@@ -7968,15 +7969,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7968,15 +7969,6 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7968 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});7969 if (sentinel != .none) extra.appendAssumeCapacity(.{@intFromEnum(sentinel)});
7969 },7970 },
79707971
7971 .un => |un| {
7972 assert(un.ty != .none);
7973 assert(un.val != .none);
7974 items.appendAssumeCapacity(.{
7975 .tag = .union_value,
7976 .data = try addExtra(extra, un),
7977 });
7978 },
7979
7980 .memoized_call => |memoized_call| {7972 .memoized_call => |memoized_call| {
7981 for (memoized_call.arg_values) |arg| assert(arg != .none);7973 for (memoized_call.arg_values) |arg| assert(arg != .none);
7982 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".fields.len +7974 try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".fields.len +
...@@ -7996,6 +7988,30 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -7996,6 +7988,30 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
7996 return gop.put();7988 return gop.put();
7997}7989}
79987990
7991pub fn getUnion(
7992 ip: *InternPool,
7993 gpa: Allocator,
7994 tid: Zcu.PerThread.Id,
7995 un: Key.Union,
7996) Allocator.Error!Index {
7997 var gop = try ip.getOrPutKey(gpa, tid, .{ .un = un });
7998 defer gop.deinit();
7999 if (gop == .existing) return gop.existing;
8000 const local = ip.getLocal(tid);
8001 const items = local.getMutableItems(gpa);
8002 const extra = local.getMutableExtra(gpa);
8003 try items.ensureUnusedCapacity(1);
8004
8005 assert(un.ty != .none);
8006 assert(un.val != .none);
8007 items.appendAssumeCapacity(.{
8008 .tag = .union_value,
8009 .data = try addExtra(extra, un),
8010 });
8011
8012 return gop.put();
8013}
8014
7999pub const UnionTypeInit = struct {8015pub const UnionTypeInit = struct {
8000 flags: packed struct {8016 flags: packed struct {
8001 runtime_tag: LoadedUnionType.RuntimeTag,8017 runtime_tag: LoadedUnionType.RuntimeTag,
src/Sema.zig+235-387
...@@ -2141,7 +2141,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2141,7 +2141,7 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
2141 const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty));2141 const addrs_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(addr_arr_ty));
21422142
2143 // var st: StackTrace = undefined;2143 // var st: StackTrace = undefined;
2144 const stack_trace_ty = try pt.getBuiltinType("StackTrace");2144 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
2145 try stack_trace_ty.resolveFields(pt);2145 try stack_trace_ty.resolveFields(pt);
2146 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));2146 const st_ptr = try err_trace_block.addTy(.alloc, try pt.singleMutPtrType(stack_trace_ty));
21472147
...@@ -4854,11 +4854,11 @@ fn validateUnionInit(...@@ -4854,11 +4854,11 @@ fn validateUnionInit(
4854 }4854 }
4855 block.instructions.shrinkRetainingCapacity(block_index);4855 block.instructions.shrinkRetainingCapacity(block_index);
48564856
4857 const union_val = try pt.intern(.{ .un = .{4857 const union_val = try pt.internUnion(.{
4858 .ty = union_ty.toIntern(),4858 .ty = union_ty.toIntern(),
4859 .tag = tag_val.toIntern(),4859 .tag = tag_val.toIntern(),
4860 .val = val.toIntern(),4860 .val = val.toIntern(),
4861 } });4861 });
4862 const union_init = Air.internedToRef(union_val);4862 const union_init = Air.internedToRef(union_val);
4863 try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store);4863 try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store);
4864 return;4864 return;
...@@ -5703,27 +5703,7 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air....@@ -5703,27 +5703,7 @@ fn addStrLit(sema: *Sema, string: InternPool.String, len: u64) CompileError!Air.
5703}5703}
57045704
5705fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {5705fn uavRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
5706 return Air.internedToRef(try sema.refValue(val));5706 return Air.internedToRef(try sema.pt.refValue(val));
5707}
5708
5709fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5710 const pt = sema.pt;
5711 const ptr_ty = (try pt.ptrTypeSema(.{
5712 .child = pt.zcu.intern_pool.typeOf(val),
5713 .flags = .{
5714 .alignment = .none,
5715 .is_const = true,
5716 .address_space = .generic,
5717 },
5718 })).toIntern();
5719 return pt.intern(.{ .ptr = .{
5720 .ty = ptr_ty,
5721 .base_addr = .{ .uav = .{
5722 .val = val,
5723 .orig_ty = ptr_ty,
5724 } },
5725 .byte_offset = 0,
5726 } });
5727}5707}
57285708
5729fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5709fn zirInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -6965,7 +6945,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref...@@ -6965,7 +6945,7 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
69656945
6966 if (!block.ownerModule().error_tracing) return .none;6946 if (!block.ownerModule().error_tracing) return .none;
69676947
6968 const stack_trace_ty = try pt.getBuiltinType("StackTrace");6948 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6969 try stack_trace_ty.resolveFields(pt);6949 try stack_trace_ty.resolveFields(pt);
6970 const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);6950 const field_name = try zcu.intern_pool.getOrPutString(gpa, pt.tid, "index", .no_embedded_nulls);
6971 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {6951 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
...@@ -7007,7 +6987,7 @@ fn popErrorReturnTrace(...@@ -7007,7 +6987,7 @@ fn popErrorReturnTrace(
7007 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or6987 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
7008 // the result is comptime-known to be a non-error. Either way, pop unconditionally.6988 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
70096989
7010 const stack_trace_ty = try pt.getBuiltinType("StackTrace");6990 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7011 try stack_trace_ty.resolveFields(pt);6991 try stack_trace_ty.resolveFields(pt);
7012 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);6992 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
7013 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);6993 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
...@@ -7033,7 +7013,7 @@ fn popErrorReturnTrace(...@@ -7033,7 +7013,7 @@ fn popErrorReturnTrace(
7033 defer then_block.instructions.deinit(gpa);7013 defer then_block.instructions.deinit(gpa);
70347014
7035 // If non-error, then pop the error return trace by restoring the index.7015 // If non-error, then pop the error return trace by restoring the index.
7036 const stack_trace_ty = try pt.getBuiltinType("StackTrace");7016 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7037 try stack_trace_ty.resolveFields(pt);7017 try stack_trace_ty.resolveFields(pt);
7038 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);7018 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
7039 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);7019 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
...@@ -7176,7 +7156,7 @@ fn zirCall(...@@ -7176,7 +7156,7 @@ fn zirCall(
7176 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only7156 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
7177 // need to clean-up our own trace if we were passed to a non-error-handling expression.7157 // need to clean-up our own trace if we were passed to a non-error-handling expression.
7178 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {7158 if (input_is_error or (pop_error_return_trace and return_ty.isError(zcu))) {
7179 const stack_trace_ty = try pt.getBuiltinType("StackTrace");7159 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7180 try stack_trace_ty.resolveFields(pt);7160 try stack_trace_ty.resolveFields(pt);
7181 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);7161 const field_name = try zcu.intern_pool.getOrPutString(sema.gpa, pt.tid, "index", .no_embedded_nulls);
7182 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);7162 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
...@@ -9327,7 +9307,7 @@ fn analyzeErrUnionPayload(...@@ -9327,7 +9307,7 @@ fn analyzeErrUnionPayload(
9327 if (safety_check and block.wantSafety() and9307 if (safety_check and block.wantSafety() and
9328 !err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu))9308 !err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu))
9329 {9309 {
9330 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);9310 try sema.addSafetyCheckUnwrapError(block, src, operand, .unwrap_errunion_err, .is_non_err);
9331 }9311 }
93329312
9333 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);9313 return block.addTyOp(.unwrap_errunion_payload, payload_ty, operand);
...@@ -9411,7 +9391,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -9411,7 +9391,7 @@ fn analyzeErrUnionPayloadPtr(
9411 if (safety_check and block.wantSafety() and9391 if (safety_check and block.wantSafety() and
9412 !err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu))9392 !err_union_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu))
9413 {9393 {
9414 try sema.panicUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);9394 try sema.addSafetyCheckUnwrapError(block, src, operand, .unwrap_errunion_err_ptr, .is_non_err_ptr);
9415 }9395 }
94169396
9417 if (initializing) {9397 if (initializing) {
...@@ -10231,7 +10211,7 @@ fn finishFunc(...@@ -10231,7 +10211,7 @@ fn finishFunc(
10231 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {10211 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
10232 // Make sure that StackTrace's fields are resolved so that the backend can10212 // Make sure that StackTrace's fields are resolved so that the backend can
10233 // lower this fn type.10213 // lower this fn type.
10234 const unresolved_stack_trace_ty = try pt.getBuiltinType("StackTrace");10214 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
10235 try unresolved_stack_trace_ty.resolveFields(pt);10215 try unresolved_stack_trace_ty.resolveFields(pt);
10236 }10216 }
1023710217
...@@ -14190,7 +14170,6 @@ fn maybeErrorUnwrap(...@@ -14190,7 +14170,6 @@ fn maybeErrorUnwrap(
14190) !bool {14170) !bool {
14191 const pt = sema.pt;14171 const pt = sema.pt;
14192 const zcu = pt.zcu;14172 const zcu = pt.zcu;
14193 if (!zcu.backendSupportsFeature(.panic_unwrap_error)) return false;
1419414173
14195 const tags = sema.code.instructions.items(.tag);14174 const tags = sema.code.instructions.items(.tag);
14196 for (body) |inst| {14175 for (body) |inst| {
...@@ -14223,25 +14202,17 @@ fn maybeErrorUnwrap(...@@ -14223,25 +14202,17 @@ fn maybeErrorUnwrap(
14223 .as_node => try sema.zirAsNode(block, inst),14202 .as_node => try sema.zirAsNode(block, inst),
14224 .field_val => try sema.zirFieldVal(block, inst),14203 .field_val => try sema.zirFieldVal(block, inst),
14225 .@"unreachable" => {14204 .@"unreachable" => {
14226 if (!zcu.comp.formatted_panics) {14205 try safetyPanicUnwrapError(sema, block, operand_src, operand);
14227 try sema.safetyPanic(block, operand_src, .unwrap_error);
14228 return true;
14229 }
14230
14231 const panic_fn = try pt.getBuiltin("panicUnwrapError");
14232 const err_return_trace = try sema.getErrorReturnTrace(block);
14233 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
14234 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
14235 return true;14206 return true;
14236 },14207 },
14237 .panic => {14208 .panic => {
14238 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;14209 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
14239 const msg_inst = try sema.resolveInst(inst_data.operand);14210 const msg_inst = try sema.resolveInst(inst_data.operand);
1424014211
14241 const panic_fn = try pt.getBuiltin("panic");14212 const panic_fn = try getPanicInnerFn(sema, block, operand_src, "call");
14242 const err_return_trace = try sema.getErrorReturnTrace(block);14213 const err_return_trace = try sema.getErrorReturnTrace(block);
14243 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };14214 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
14244 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");14215 try sema.callBuiltin(block, operand_src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
14245 return true;14216 return true;
14246 },14217 },
14247 else => unreachable,14218 else => unreachable,
...@@ -18275,7 +18246,7 @@ fn zirBuiltinSrc(...@@ -18275,7 +18246,7 @@ fn zirBuiltinSrc(
18275 } });18246 } });
18276 };18247 };
1827718248
18278 const src_loc_ty = try pt.getBuiltinType("SourceLocation");18249 const src_loc_ty = try sema.getBuiltinType("SourceLocation");
18279 const fields = .{18250 const fields = .{
18280 // module: [:0]const u8,18251 // module: [:0]const u8,
18281 module_name_val,18252 module_name_val,
...@@ -18302,7 +18273,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18302,7 +18273,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18302 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;18273 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
18303 const src = block.nodeOffset(inst_data.src_node);18274 const src = block.nodeOffset(inst_data.src_node);
18304 const ty = try sema.resolveType(block, src, inst_data.operand);18275 const ty = try sema.resolveType(block, src, inst_data.operand);
18305 const type_info_ty = try pt.getBuiltinType("Type");18276 const type_info_ty = try sema.getBuiltinType("Type");
18306 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;18277 const type_info_tag_ty = type_info_ty.unionTagType(zcu).?;
1830718278
18308 if (ty.typeDeclInst(zcu)) |type_decl_inst| {18279 if (ty.typeDeclInst(zcu)) |type_decl_inst| {
...@@ -18319,29 +18290,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18319,29 +18290,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18319 .undefined,18290 .undefined,
18320 .null,18291 .null,
18321 .enum_literal,18292 .enum_literal,
18322 => |type_info_tag| return Air.internedToRef((try pt.intern(.{ .un = .{18293 => |type_info_tag| return unionInitFromEnumTag(sema, block, src, type_info_ty, @intFromEnum(type_info_tag), .void_value),
18323 .ty = type_info_ty.toIntern(),
18324 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(type_info_tag))).toIntern(),
18325 .val = .void_value,
18326 } }))),
18327 .@"fn" => {
18328 const fn_info_nav = try sema.namespaceLookup(
18329 block,
18330 src,
18331 type_info_ty.getNamespaceIndex(zcu),
18332 try ip.getOrPutString(gpa, pt.tid, "Fn", .no_embedded_nulls),
18333 ) orelse @panic("std.builtin.Type is corrupt");
18334 try sema.ensureNavResolved(src, fn_info_nav);
18335 const fn_info_ty = Type.fromInterned(ip.getNav(fn_info_nav).status.resolved.val);
1833618294
18337 const param_info_nav = try sema.namespaceLookup(18295 .@"fn" => {
18338 block,18296 const fn_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Fn");
18339 src,18297 const param_info_ty = try getBuiltinInnerType(sema, block, src, fn_info_ty, "Type.Fn", "Param");
18340 fn_info_ty.getNamespaceIndex(zcu),
18341 try ip.getOrPutString(gpa, pt.tid, "Param", .no_embedded_nulls),
18342 ) orelse @panic("std.builtin.Type is corrupt");
18343 try sema.ensureNavResolved(src, param_info_nav);
18344 const param_info_ty = Type.fromInterned(ip.getNav(param_info_nav).status.resolved.val);
1834518298
18346 const func_ty_info = zcu.typeToFunc(ty).?;18299 const func_ty_info = zcu.typeToFunc(ty).?;
18347 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);18300 const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len);
...@@ -18411,7 +18364,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18411,7 +18364,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18411 func_ty_info.return_type,18364 func_ty_info.return_type,
18412 } });18365 } });
1841318366
18414 const callconv_ty = try pt.getBuiltinType("CallingConvention");18367 const callconv_ty = try sema.getBuiltinType("CallingConvention");
1841518368
18416 const field_values = .{18369 const field_values = .{
18417 // calling_convention: CallingConvention,18370 // calling_convention: CallingConvention,
...@@ -18425,26 +18378,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18425,26 +18378,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18425 // args: []const Fn.Param,18378 // args: []const Fn.Param,
18426 args_val,18379 args_val,
18427 };18380 };
18428 return Air.internedToRef((try pt.intern(.{ .un = .{18381 return Air.internedToRef((try pt.internUnion(.{
18429 .ty = type_info_ty.toIntern(),18382 .ty = type_info_ty.toIntern(),
18430 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"fn"))).toIntern(),18383 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"fn"))).toIntern(),
18431 .val = try pt.intern(.{ .aggregate = .{18384 .val = try pt.intern(.{ .aggregate = .{
18432 .ty = fn_info_ty.toIntern(),18385 .ty = fn_info_ty.toIntern(),
18433 .storage = .{ .elems = &field_values },18386 .storage = .{ .elems = &field_values },
18434 } }),18387 } }),
18435 } })));18388 })));
18436 },18389 },
18437 .int => {18390 .int => {
18438 const int_info_nav = try sema.namespaceLookup(18391 const int_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Int");
18439 block,18392 const signedness_ty = try sema.getBuiltinType("Signedness");
18440 src,
18441 type_info_ty.getNamespaceIndex(zcu),
18442 try ip.getOrPutString(gpa, pt.tid, "Int", .no_embedded_nulls),
18443 ) orelse @panic("std.builtin.Type is corrupt");
18444 try sema.ensureNavResolved(src, int_info_nav);
18445 const int_info_ty = Type.fromInterned(ip.getNav(int_info_nav).status.resolved.val);
18446
18447 const signedness_ty = try pt.getBuiltinType("Signedness");
18448 const info = ty.intInfo(zcu);18393 const info = ty.intInfo(zcu);
18449 const field_values = .{18394 const field_values = .{
18450 // signedness: Signedness,18395 // signedness: Signedness,
...@@ -18452,37 +18397,30 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18452,37 +18397,30 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18452 // bits: u16,18397 // bits: u16,
18453 (try pt.intValue(Type.u16, info.bits)).toIntern(),18398 (try pt.intValue(Type.u16, info.bits)).toIntern(),
18454 };18399 };
18455 return Air.internedToRef((try pt.intern(.{ .un = .{18400 return Air.internedToRef((try pt.internUnion(.{
18456 .ty = type_info_ty.toIntern(),18401 .ty = type_info_ty.toIntern(),
18457 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.int))).toIntern(),18402 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.int))).toIntern(),
18458 .val = try pt.intern(.{ .aggregate = .{18403 .val = try pt.intern(.{ .aggregate = .{
18459 .ty = int_info_ty.toIntern(),18404 .ty = int_info_ty.toIntern(),
18460 .storage = .{ .elems = &field_values },18405 .storage = .{ .elems = &field_values },
18461 } }),18406 } }),
18462 } })));18407 })));
18463 },18408 },
18464 .float => {18409 .float => {
18465 const float_info_nav = try sema.namespaceLookup(18410 const float_info_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Float");
18466 block,
18467 src,
18468 type_info_ty.getNamespaceIndex(zcu),
18469 try ip.getOrPutString(gpa, pt.tid, "Float", .no_embedded_nulls),
18470 ) orelse @panic("std.builtin.Type is corrupt");
18471 try sema.ensureNavResolved(src, float_info_nav);
18472 const float_info_ty = Type.fromInterned(ip.getNav(float_info_nav).status.resolved.val);
1847318411
18474 const field_vals = .{18412 const field_vals = .{
18475 // bits: u16,18413 // bits: u16,
18476 (try pt.intValue(Type.u16, ty.bitSize(zcu))).toIntern(),18414 (try pt.intValue(Type.u16, ty.bitSize(zcu))).toIntern(),
18477 };18415 };
18478 return Air.internedToRef((try pt.intern(.{ .un = .{18416 return Air.internedToRef((try pt.internUnion(.{
18479 .ty = type_info_ty.toIntern(),18417 .ty = type_info_ty.toIntern(),
18480 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.float))).toIntern(),18418 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.float))).toIntern(),
18481 .val = try pt.intern(.{ .aggregate = .{18419 .val = try pt.intern(.{ .aggregate = .{
18482 .ty = float_info_ty.toIntern(),18420 .ty = float_info_ty.toIntern(),
18483 .storage = .{ .elems = &field_vals },18421 .storage = .{ .elems = &field_vals },
18484 } }),18422 } }),
18485 } })));18423 })));
18486 },18424 },
18487 .pointer => {18425 .pointer => {
18488 const info = ty.ptrInfo(zcu);18426 const info = ty.ptrInfo(zcu);
...@@ -18491,27 +18429,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18491,27 +18429,9 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18491 else18429 else
18492 try Type.fromInterned(info.child).lazyAbiAlignment(pt);18430 try Type.fromInterned(info.child).lazyAbiAlignment(pt);
1849318431
18494 const addrspace_ty = try pt.getBuiltinType("AddressSpace");18432 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
18495 const pointer_ty = t: {18433 const pointer_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Pointer");
18496 const nav = try sema.namespaceLookup(18434 const ptr_size_ty = try getBuiltinInnerType(sema, block, src, pointer_ty, "Type.Pointer", "Size");
18497 block,
18498 src,
18499 (try pt.getBuiltinType("Type")).getNamespaceIndex(zcu),
18500 try ip.getOrPutString(gpa, pt.tid, "Pointer", .no_embedded_nulls),
18501 ) orelse @panic("std.builtin.Type is corrupt");
18502 try sema.ensureNavResolved(src, nav);
18503 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18504 };
18505 const ptr_size_ty = t: {
18506 const nav = try sema.namespaceLookup(
18507 block,
18508 src,
18509 pointer_ty.getNamespaceIndex(zcu),
18510 try ip.getOrPutString(gpa, pt.tid, "Size", .no_embedded_nulls),
18511 ) orelse @panic("std.builtin.Type is corrupt");
18512 try sema.ensureNavResolved(src, nav);
18513 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18514 };
1851518435
18516 const field_values = .{18436 const field_values = .{
18517 // size: Size,18437 // size: Size,
...@@ -18534,26 +18454,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18534,26 +18454,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18534 else => Value.fromInterned(info.sentinel),18454 else => Value.fromInterned(info.sentinel),
18535 })).toIntern(),18455 })).toIntern(),
18536 };18456 };
18537 return Air.internedToRef((try pt.intern(.{ .un = .{18457 return Air.internedToRef((try pt.internUnion(.{
18538 .ty = type_info_ty.toIntern(),18458 .ty = type_info_ty.toIntern(),
18539 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.pointer))).toIntern(),18459 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.pointer))).toIntern(),
18540 .val = try pt.intern(.{ .aggregate = .{18460 .val = try pt.intern(.{ .aggregate = .{
18541 .ty = pointer_ty.toIntern(),18461 .ty = pointer_ty.toIntern(),
18542 .storage = .{ .elems = &field_values },18462 .storage = .{ .elems = &field_values },
18543 } }),18463 } }),
18544 } })));18464 })));
18545 },18465 },
18546 .array => {18466 .array => {
18547 const array_field_ty = t: {18467 const array_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Array");
18548 const nav = try sema.namespaceLookup(
18549 block,
18550 src,
18551 type_info_ty.getNamespaceIndex(zcu),
18552 try ip.getOrPutString(gpa, pt.tid, "Array", .no_embedded_nulls),
18553 ) orelse @panic("std.builtin.Type is corrupt");
18554 try sema.ensureNavResolved(src, nav);
18555 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18556 };
1855718468
18558 const info = ty.arrayInfo(zcu);18469 const info = ty.arrayInfo(zcu);
18559 const field_values = .{18470 const field_values = .{
...@@ -18564,26 +18475,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18564,26 +18475,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18564 // sentinel: ?*const anyopaque,18475 // sentinel: ?*const anyopaque,
18565 (try sema.optRefValue(info.sentinel)).toIntern(),18476 (try sema.optRefValue(info.sentinel)).toIntern(),
18566 };18477 };
18567 return Air.internedToRef((try pt.intern(.{ .un = .{18478 return Air.internedToRef((try pt.internUnion(.{
18568 .ty = type_info_ty.toIntern(),18479 .ty = type_info_ty.toIntern(),
18569 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.array))).toIntern(),18480 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.array))).toIntern(),
18570 .val = try pt.intern(.{ .aggregate = .{18481 .val = try pt.intern(.{ .aggregate = .{
18571 .ty = array_field_ty.toIntern(),18482 .ty = array_field_ty.toIntern(),
18572 .storage = .{ .elems = &field_values },18483 .storage = .{ .elems = &field_values },
18573 } }),18484 } }),
18574 } })));18485 })));
18575 },18486 },
18576 .vector => {18487 .vector => {
18577 const vector_field_ty = t: {18488 const vector_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Vector");
18578 const nav = try sema.namespaceLookup(
18579 block,
18580 src,
18581 type_info_ty.getNamespaceIndex(zcu),
18582 try ip.getOrPutString(gpa, pt.tid, "Vector", .no_embedded_nulls),
18583 ) orelse @panic("std.builtin.Type is corrupt");
18584 try sema.ensureNavResolved(src, nav);
18585 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18586 };
1858718489
18588 const info = ty.arrayInfo(zcu);18490 const info = ty.arrayInfo(zcu);
18589 const field_values = .{18491 const field_values = .{
...@@ -18592,52 +18494,34 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18592,52 +18494,34 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18592 // child: type,18494 // child: type,
18593 info.elem_type.toIntern(),18495 info.elem_type.toIntern(),
18594 };18496 };
18595 return Air.internedToRef((try pt.intern(.{ .un = .{18497 return Air.internedToRef((try pt.internUnion(.{
18596 .ty = type_info_ty.toIntern(),18498 .ty = type_info_ty.toIntern(),
18597 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.vector))).toIntern(),18499 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.vector))).toIntern(),
18598 .val = try pt.intern(.{ .aggregate = .{18500 .val = try pt.intern(.{ .aggregate = .{
18599 .ty = vector_field_ty.toIntern(),18501 .ty = vector_field_ty.toIntern(),
18600 .storage = .{ .elems = &field_values },18502 .storage = .{ .elems = &field_values },
18601 } }),18503 } }),
18602 } })));18504 })));
18603 },18505 },
18604 .optional => {18506 .optional => {
18605 const optional_field_ty = t: {18507 const optional_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Optional");
18606 const nav = try sema.namespaceLookup(
18607 block,
18608 src,
18609 type_info_ty.getNamespaceIndex(zcu),
18610 try ip.getOrPutString(gpa, pt.tid, "Optional", .no_embedded_nulls),
18611 ) orelse @panic("std.builtin.Type is corrupt");
18612 try sema.ensureNavResolved(src, nav);
18613 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18614 };
1861518508
18616 const field_values = .{18509 const field_values = .{
18617 // child: type,18510 // child: type,
18618 ty.optionalChild(zcu).toIntern(),18511 ty.optionalChild(zcu).toIntern(),
18619 };18512 };
18620 return Air.internedToRef((try pt.intern(.{ .un = .{18513 return Air.internedToRef((try pt.internUnion(.{
18621 .ty = type_info_ty.toIntern(),18514 .ty = type_info_ty.toIntern(),
18622 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.optional))).toIntern(),18515 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.optional))).toIntern(),
18623 .val = try pt.intern(.{ .aggregate = .{18516 .val = try pt.intern(.{ .aggregate = .{
18624 .ty = optional_field_ty.toIntern(),18517 .ty = optional_field_ty.toIntern(),
18625 .storage = .{ .elems = &field_values },18518 .storage = .{ .elems = &field_values },
18626 } }),18519 } }),
18627 } })));18520 })));
18628 },18521 },
18629 .error_set => {18522 .error_set => {
18630 // Get the Error type18523 // Get the Error type
18631 const error_field_ty = t: {18524 const error_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Error");
18632 const nav = try sema.namespaceLookup(
18633 block,
18634 src,
18635 type_info_ty.getNamespaceIndex(zcu),
18636 try ip.getOrPutString(gpa, pt.tid, "Error", .no_embedded_nulls),
18637 ) orelse @panic("std.builtin.Type is corrupt");
18638 try sema.ensureNavResolved(src, nav);
18639 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18640 };
1864118525
18642 // Build our list of Error values18526 // Build our list of Error values
18643 // Optional value is only null if anyerror18527 // Optional value is only null if anyerror
...@@ -18726,23 +18610,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18726,23 +18610,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18726 } });18610 } });
1872718611
18728 // Construct Type{ .error_set = errors_val }18612 // Construct Type{ .error_set = errors_val }
18729 return Air.internedToRef((try pt.intern(.{ .un = .{18613 return Air.internedToRef((try pt.internUnion(.{
18730 .ty = type_info_ty.toIntern(),18614 .ty = type_info_ty.toIntern(),
18731 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.error_set))).toIntern(),18615 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.error_set))).toIntern(),
18732 .val = errors_val,18616 .val = errors_val,
18733 } })));18617 })));
18734 },18618 },
18735 .error_union => {18619 .error_union => {
18736 const error_union_field_ty = t: {18620 const error_union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ErrorUnion");
18737 const nav = try sema.namespaceLookup(
18738 block,
18739 src,
18740 type_info_ty.getNamespaceIndex(zcu),
18741 try ip.getOrPutString(gpa, pt.tid, "ErrorUnion", .no_embedded_nulls),
18742 ) orelse @panic("std.builtin.Type is corrupt");
18743 try sema.ensureNavResolved(src, nav);
18744 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18745 };
1874618621
18747 const field_values = .{18622 const field_values = .{
18748 // error_set: type,18623 // error_set: type,
...@@ -18750,28 +18625,19 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18750,28 +18625,19 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18750 // payload: type,18625 // payload: type,
18751 ty.errorUnionPayload(zcu).toIntern(),18626 ty.errorUnionPayload(zcu).toIntern(),
18752 };18627 };
18753 return Air.internedToRef((try pt.intern(.{ .un = .{18628 return Air.internedToRef((try pt.internUnion(.{
18754 .ty = type_info_ty.toIntern(),18629 .ty = type_info_ty.toIntern(),
18755 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.error_union))).toIntern(),18630 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.error_union))).toIntern(),
18756 .val = try pt.intern(.{ .aggregate = .{18631 .val = try pt.intern(.{ .aggregate = .{
18757 .ty = error_union_field_ty.toIntern(),18632 .ty = error_union_field_ty.toIntern(),
18758 .storage = .{ .elems = &field_values },18633 .storage = .{ .elems = &field_values },
18759 } }),18634 } }),
18760 } })));18635 })));
18761 },18636 },
18762 .@"enum" => {18637 .@"enum" => {
18763 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);18638 const is_exhaustive = Value.makeBool(ip.loadEnumType(ty.toIntern()).tag_mode != .nonexhaustive);
1876418639
18765 const enum_field_ty = t: {18640 const enum_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "EnumField");
18766 const nav = try sema.namespaceLookup(
18767 block,
18768 src,
18769 type_info_ty.getNamespaceIndex(zcu),
18770 try ip.getOrPutString(gpa, pt.tid, "EnumField", .no_embedded_nulls),
18771 ) orelse @panic("std.builtin.Type is corrupt");
18772 try sema.ensureNavResolved(src, nav);
18773 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18774 };
1877518641
18776 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);18642 const enum_field_vals = try sema.arena.alloc(InternPool.Index, ip.loadEnumType(ty.toIntern()).names.len);
18777 for (enum_field_vals, 0..) |*field_val, tag_index| {18643 for (enum_field_vals, 0..) |*field_val, tag_index| {
...@@ -18858,16 +18724,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18858,16 +18724,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1885818724
18859 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional());18725 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
1886018726
18861 const type_enum_ty = t: {18727 const type_enum_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Enum");
18862 const nav = try sema.namespaceLookup(
18863 block,
18864 src,
18865 type_info_ty.getNamespaceIndex(zcu),
18866 try ip.getOrPutString(gpa, pt.tid, "Enum", .no_embedded_nulls),
18867 ) orelse @panic("std.builtin.Type is corrupt");
18868 try sema.ensureNavResolved(src, nav);
18869 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18870 };
1887118728
18872 const field_values = .{18729 const field_values = .{
18873 // tag_type: type,18730 // tag_type: type,
...@@ -18879,37 +18736,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18879,37 +18736,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18879 // is_exhaustive: bool,18736 // is_exhaustive: bool,
18880 is_exhaustive.toIntern(),18737 is_exhaustive.toIntern(),
18881 };18738 };
18882 return Air.internedToRef((try pt.intern(.{ .un = .{18739 return Air.internedToRef((try pt.internUnion(.{
18883 .ty = type_info_ty.toIntern(),18740 .ty = type_info_ty.toIntern(),
18884 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"enum"))).toIntern(),18741 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"enum"))).toIntern(),
18885 .val = try pt.intern(.{ .aggregate = .{18742 .val = try pt.intern(.{ .aggregate = .{
18886 .ty = type_enum_ty.toIntern(),18743 .ty = type_enum_ty.toIntern(),
18887 .storage = .{ .elems = &field_values },18744 .storage = .{ .elems = &field_values },
18888 } }),18745 } }),
18889 } })));18746 })));
18890 },18747 },
18891 .@"union" => {18748 .@"union" => {
18892 const type_union_ty = t: {18749 const type_union_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Union");
18893 const nav = try sema.namespaceLookup(18750 const union_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "UnionField");
18894 block,
18895 src,
18896 type_info_ty.getNamespaceIndex(zcu),
18897 try ip.getOrPutString(gpa, pt.tid, "Union", .no_embedded_nulls),
18898 ) orelse @panic("std.builtin.Type is corrupt");
18899 try sema.ensureNavResolved(src, nav);
18900 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18901 };
18902
18903 const union_field_ty = t: {
18904 const nav = try sema.namespaceLookup(
18905 block,
18906 src,
18907 type_info_ty.getNamespaceIndex(zcu),
18908 try ip.getOrPutString(gpa, pt.tid, "UnionField", .no_embedded_nulls),
18909 ) orelse @panic("std.builtin.Type is corrupt");
18910 try sema.ensureNavResolved(src, nav);
18911 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
18912 };
1891318751
18914 try ty.resolveLayout(pt); // Getting alignment requires type layout18752 try ty.resolveLayout(pt); // Getting alignment requires type layout
18915 const union_obj = zcu.typeToUnion(ty).?;18753 const union_obj = zcu.typeToUnion(ty).?;
...@@ -19004,16 +18842,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19004,16 +18842,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19004 .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none,18842 .val = if (ty.unionTagType(zcu)) |tag_ty| tag_ty.toIntern() else .none,
19005 } });18843 } });
1900618844
19007 const container_layout_ty = t: {18845 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");
19008 const nav = try sema.namespaceLookup(
19009 block,
19010 src,
19011 (try pt.getBuiltinType("Type")).getNamespaceIndex(zcu),
19012 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
19013 ) orelse @panic("std.builtin.Type is corrupt");
19014 try sema.ensureNavResolved(src, nav);
19015 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
19016 };
1901718846
19018 const field_values = .{18847 const field_values = .{
19019 // layout: ContainerLayout,18848 // layout: ContainerLayout,
...@@ -19026,37 +18855,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19026,37 +18855,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19026 // decls: []const Declaration,18855 // decls: []const Declaration,
19027 decls_val,18856 decls_val,
19028 };18857 };
19029 return Air.internedToRef((try pt.intern(.{ .un = .{18858 return Air.internedToRef((try pt.internUnion(.{
19030 .ty = type_info_ty.toIntern(),18859 .ty = type_info_ty.toIntern(),
19031 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"union"))).toIntern(),18860 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"union"))).toIntern(),
19032 .val = try pt.intern(.{ .aggregate = .{18861 .val = try pt.intern(.{ .aggregate = .{
19033 .ty = type_union_ty.toIntern(),18862 .ty = type_union_ty.toIntern(),
19034 .storage = .{ .elems = &field_values },18863 .storage = .{ .elems = &field_values },
19035 } }),18864 } }),
19036 } })));18865 })));
19037 },18866 },
19038 .@"struct" => {18867 .@"struct" => {
19039 const type_struct_ty = t: {18868 const type_struct_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Struct");
19040 const nav = try sema.namespaceLookup(18869 const struct_field_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "StructField");
19041 block,
19042 src,
19043 type_info_ty.getNamespaceIndex(zcu),
19044 try ip.getOrPutString(gpa, pt.tid, "Struct", .no_embedded_nulls),
19045 ) orelse @panic("std.builtin.Type is corrupt");
19046 try sema.ensureNavResolved(src, nav);
19047 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
19048 };
19049
19050 const struct_field_ty = t: {
19051 const nav = try sema.namespaceLookup(
19052 block,
19053 src,
19054 type_info_ty.getNamespaceIndex(zcu),
19055 try ip.getOrPutString(gpa, pt.tid, "StructField", .no_embedded_nulls),
19056 ) orelse @panic("std.builtin.Type is corrupt");
19057 try sema.ensureNavResolved(src, nav);
19058 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
19059 };
1906018870
19061 try ty.resolveLayout(pt); // Getting alignment requires type layout18871 try ty.resolveLayout(pt); // Getting alignment requires type layout
1906218872
...@@ -19233,16 +19043,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19233,16 +19043,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19233 } else .none,19043 } else .none,
19234 } });19044 } });
1923519045
19236 const container_layout_ty = t: {19046 const container_layout_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "ContainerLayout");
19237 const nav = try sema.namespaceLookup(
19238 block,
19239 src,
19240 (try pt.getBuiltinType("Type")).getNamespaceIndex(zcu),
19241 try ip.getOrPutString(gpa, pt.tid, "ContainerLayout", .no_embedded_nulls),
19242 ) orelse @panic("std.builtin.Type is corrupt");
19243 try sema.ensureNavResolved(src, nav);
19244 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
19245 };
1924619047
19247 const layout = ty.containerLayout(zcu);19048 const layout = ty.containerLayout(zcu);
1924819049
...@@ -19258,26 +19059,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19258,26 +19059,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19258 // is_tuple: bool,19059 // is_tuple: bool,
19259 Value.makeBool(ty.isTuple(zcu)).toIntern(),19060 Value.makeBool(ty.isTuple(zcu)).toIntern(),
19260 };19061 };
19261 return Air.internedToRef((try pt.intern(.{ .un = .{19062 return Air.internedToRef((try pt.internUnion(.{
19262 .ty = type_info_ty.toIntern(),19063 .ty = type_info_ty.toIntern(),
19263 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"struct"))).toIntern(),19064 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"struct"))).toIntern(),
19264 .val = try pt.intern(.{ .aggregate = .{19065 .val = try pt.intern(.{ .aggregate = .{
19265 .ty = type_struct_ty.toIntern(),19066 .ty = type_struct_ty.toIntern(),
19266 .storage = .{ .elems = &field_values },19067 .storage = .{ .elems = &field_values },
19267 } }),19068 } }),
19268 } })));19069 })));
19269 },19070 },
19270 .@"opaque" => {19071 .@"opaque" => {
19271 const type_opaque_ty = t: {19072 const type_opaque_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Opaque");
19272 const nav = try sema.namespaceLookup(
19273 block,
19274 src,
19275 type_info_ty.getNamespaceIndex(zcu),
19276 try ip.getOrPutString(gpa, pt.tid, "Opaque", .no_embedded_nulls),
19277 ) orelse @panic("std.builtin.Type is corrupt");
19278 try sema.ensureNavResolved(src, nav);
19279 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
19280 };
1928119073
19282 try ty.resolveFields(pt);19074 try ty.resolveFields(pt);
19283 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));19075 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespace(zcu));
...@@ -19286,14 +19078,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -19286,14 +19078,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
19286 // decls: []const Declaration,19078 // decls: []const Declaration,
19287 decls_val,19079 decls_val,
19288 };19080 };
19289 return Air.internedToRef((try pt.intern(.{ .un = .{19081 return Air.internedToRef((try pt.internUnion(.{
19290 .ty = type_info_ty.toIntern(),19082 .ty = type_info_ty.toIntern(),
19291 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"opaque"))).toIntern(),19083 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.builtin.TypeId.@"opaque"))).toIntern(),
19292 .val = try pt.intern(.{ .aggregate = .{19084 .val = try pt.intern(.{ .aggregate = .{
19293 .ty = type_opaque_ty.toIntern(),19085 .ty = type_opaque_ty.toIntern(),
19294 .storage = .{ .elems = &field_values },19086 .storage = .{ .elems = &field_values },
19295 } }),19087 } }),
19296 } })));19088 })));
19297 },19089 },
19298 .frame => return sema.failWithUseOfAsync(block, src),19090 .frame => return sema.failWithUseOfAsync(block, src),
19299 .@"anyframe" => return sema.failWithUseOfAsync(block, src),19091 .@"anyframe" => return sema.failWithUseOfAsync(block, src),
...@@ -19309,19 +19101,9 @@ fn typeInfoDecls(...@@ -19309,19 +19101,9 @@ fn typeInfoDecls(
19309) CompileError!InternPool.Index {19101) CompileError!InternPool.Index {
19310 const pt = sema.pt;19102 const pt = sema.pt;
19311 const zcu = pt.zcu;19103 const zcu = pt.zcu;
19312 const ip = &zcu.intern_pool;
19313 const gpa = sema.gpa;19104 const gpa = sema.gpa;
1931419105
19315 const declaration_ty = t: {19106 const declaration_ty = try getBuiltinInnerType(sema, block, src, type_info_ty, "Type", "Declaration");
19316 const nav = try sema.namespaceLookup(
19317 block,
19318 src,
19319 type_info_ty.getNamespaceIndex(zcu),
19320 try ip.getOrPutString(gpa, pt.tid, "Declaration", .no_embedded_nulls),
19321 ) orelse @panic("std.builtin.Type is corrupt");
19322 try sema.ensureNavResolved(src, nav);
19323 break :t Type.fromInterned(ip.getNav(nav).status.resolved.val);
19324 };
1932519107
19326 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);19108 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
19327 defer decl_vals.deinit();19109 defer decl_vals.deinit();
...@@ -20265,11 +20047,11 @@ fn retWithErrTracing(...@@ -20265,11 +20047,11 @@ fn retWithErrTracing(
20265 else => true,20047 else => true,
20266 };20048 };
20267 const gpa = sema.gpa;20049 const gpa = sema.gpa;
20268 const stack_trace_ty = try pt.getBuiltinType("StackTrace");20050 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
20269 try stack_trace_ty.resolveFields(pt);20051 try stack_trace_ty.resolveFields(pt);
20270 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);20052 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
20271 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);20053 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
20272 const return_err_fn = try pt.getBuiltin("returnError");20054 const return_err_fn = try sema.getBuiltin("returnError");
20273 const args: [1]Air.Inst.Ref = .{err_return_trace};20055 const args: [1]Air.Inst.Ref = .{err_return_trace};
2027420056
20275 if (!need_check) {20057 if (!need_check) {
...@@ -20805,19 +20587,32 @@ fn unionInit(...@@ -20805,19 +20587,32 @@ fn unionInit(
20805 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);20587 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_src);
20806 const field_ty = Type.fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);20588 const field_ty = Type.fromInterned(zcu.typeToUnion(union_ty).?.field_types.get(ip)[field_index]);
20807 const init = try sema.coerce(block, field_ty, uncasted_init, init_src);20589 const init = try sema.coerce(block, field_ty, uncasted_init, init_src);
20590 _ = union_ty_src;
20591 return unionInitFromEnumTag(sema, block, init_src, union_ty, field_index, init);
20592}
20593
20594fn unionInitFromEnumTag(
20595 sema: *Sema,
20596 block: *Block,
20597 init_src: LazySrcLoc,
20598 union_ty: Type,
20599 field_index: u32,
20600 init: Air.Inst.Ref,
20601) !Air.Inst.Ref {
20602 const pt = sema.pt;
20603 const zcu = pt.zcu;
2080820604
20809 if (try sema.resolveValue(init)) |init_val| {20605 if (try sema.resolveValue(init)) |init_val| {
20810 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);20606 const tag_ty = union_ty.unionTagTypeHypothetical(zcu);
20811 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);20607 const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index);
20812 return Air.internedToRef((try pt.intern(.{ .un = .{20608 return Air.internedToRef((try pt.internUnion(.{
20813 .ty = union_ty.toIntern(),20609 .ty = union_ty.toIntern(),
20814 .tag = tag_val.toIntern(),20610 .tag = tag_val.toIntern(),
20815 .val = init_val.toIntern(),20611 .val = init_val.toIntern(),
20816 } })));20612 })));
20817 }20613 }
2081820614
20819 try sema.requireRuntimeBlock(block, init_src, null);20615 try sema.requireRuntimeBlock(block, init_src, null);
20820 _ = union_ty_src;
20821 return block.addUnionInit(union_ty, field_index, init);20616 return block.addUnionInit(union_ty, field_index, init);
20822}20617}
2082320618
...@@ -20949,11 +20744,11 @@ fn zirStructInit(...@@ -20949,11 +20744,11 @@ fn zirStructInit(
20949 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);20744 const init_inst = try sema.coerce(block, field_ty, uncoerced_init_inst, field_src);
2095020745
20951 if (try sema.resolveValue(init_inst)) |val| {20746 if (try sema.resolveValue(init_inst)) |val| {
20952 const struct_val = Value.fromInterned(try pt.intern(.{ .un = .{20747 const struct_val = Value.fromInterned(try pt.internUnion(.{
20953 .ty = resolved_ty.toIntern(),20748 .ty = resolved_ty.toIntern(),
20954 .tag = tag_val.toIntern(),20749 .tag = tag_val.toIntern(),
20955 .val = val.toIntern(),20750 .val = val.toIntern(),
20956 } }));20751 }));
20957 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);20752 const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src);
20958 const final_val = (try sema.resolveValue(final_val_inst)).?;20753 const final_val = (try sema.resolveValue(final_val_inst)).?;
20959 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);20754 return sema.addConstantMaybeRef(final_val.toIntern(), is_ref);
...@@ -21660,7 +21455,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -21660,7 +21455,7 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
21660 const pt = sema.pt;21455 const pt = sema.pt;
21661 const zcu = pt.zcu;21456 const zcu = pt.zcu;
21662 const ip = &zcu.intern_pool;21457 const ip = &zcu.intern_pool;
21663 const stack_trace_ty = try pt.getBuiltinType("StackTrace");21458 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
21664 try stack_trace_ty.resolveFields(pt);21459 try stack_trace_ty.resolveFields(pt);
21665 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);21460 const ptr_stack_trace_ty = try pt.singleMutPtrType(stack_trace_ty);
21666 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());21461 const opt_ptr_stack_trace_ty = try pt.optionalType(ptr_stack_trace_ty.toIntern());
...@@ -21873,7 +21668,6 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21873,7 +21668,6 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21873 const pt = sema.pt;21668 const pt = sema.pt;
21874 const zcu = pt.zcu;21669 const zcu = pt.zcu;
21875 const ip = &zcu.intern_pool;21670 const ip = &zcu.intern_pool;
21876
21877 try operand_ty.resolveLayout(pt);21671 try operand_ty.resolveLayout(pt);
21878 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {21672 const enum_ty = switch (operand_ty.zigTypeTag(zcu)) {
21879 .enum_literal => {21673 .enum_literal => {
...@@ -21950,7 +21744,7 @@ fn zirReify(...@@ -21950,7 +21744,7 @@ fn zirReify(
21950 },21744 },
21951 },21745 },
21952 };21746 };
21953 const type_info_ty = try pt.getBuiltinType("Type");21747 const type_info_ty = try sema.getBuiltinType("Type");
21954 const uncasted_operand = try sema.resolveInst(extra.operand);21748 const uncasted_operand = try sema.resolveInst(extra.operand);
21955 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);21749 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
21956 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{21750 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
...@@ -23152,7 +22946,7 @@ fn reifyStruct(...@@ -23152,7 +22946,7 @@ fn reifyStruct(
2315222946
23153fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {22947fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
23154 const pt = sema.pt;22948 const pt = sema.pt;
23155 const va_list_ty = try pt.getBuiltinType("VaList");22949 const va_list_ty = try sema.getBuiltinType("VaList");
23156 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);22950 const va_list_ptr = try pt.singleMutPtrType(va_list_ty);
2315722951
23158 const inst = try sema.resolveInst(zir_ref);22952 const inst = try sema.resolveInst(zir_ref);
...@@ -23191,7 +22985,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -23191,7 +22985,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
23191 const va_list_src = block.builtinCallArgSrc(extra.node, 0);22985 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2319222986
23193 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);22987 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
23194 const va_list_ty = try sema.pt.getBuiltinType("VaList");22988 const va_list_ty = try sema.getBuiltinType("VaList");
2319522989
23196 try sema.requireRuntimeBlock(block, src, null);22990 try sema.requireRuntimeBlock(block, src, null);
23197 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);22991 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
...@@ -23211,7 +23005,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -23211,7 +23005,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
23211fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {23005fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
23212 const src = block.nodeOffset(@bitCast(extended.operand));23006 const src = block.nodeOffset(@bitCast(extended.operand));
2321323007
23214 const va_list_ty = try sema.pt.getBuiltinType("VaList");23008 const va_list_ty = try sema.getBuiltinType("VaList");
23215 try sema.requireRuntimeBlock(block, src, null);23009 try sema.requireRuntimeBlock(block, src, null);
23216 return block.addInst(.{23010 return block.addInst(.{
23217 .tag = .c_va_start,23011 .tag = .c_va_start,
...@@ -24823,7 +24617,7 @@ fn resolveExportOptions(...@@ -24823,7 +24617,7 @@ fn resolveExportOptions(
24823 const zcu = pt.zcu;24617 const zcu = pt.zcu;
24824 const gpa = sema.gpa;24618 const gpa = sema.gpa;
24825 const ip = &zcu.intern_pool;24619 const ip = &zcu.intern_pool;
24826 const export_options_ty = try pt.getBuiltinType("ExportOptions");24620 const export_options_ty = try sema.getBuiltinType("ExportOptions");
24827 const air_ref = try sema.resolveInst(zir_ref);24621 const air_ref = try sema.resolveInst(zir_ref);
24828 const options = try sema.coerce(block, export_options_ty, air_ref, src);24622 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2482924623
...@@ -24887,7 +24681,7 @@ fn resolveBuiltinEnum(...@@ -24887,7 +24681,7 @@ fn resolveBuiltinEnum(
24887 reason: NeededComptimeReason,24681 reason: NeededComptimeReason,
24888) CompileError!@field(std.builtin, name) {24682) CompileError!@field(std.builtin, name) {
24889 const pt = sema.pt;24683 const pt = sema.pt;
24890 const ty = try pt.getBuiltinType(name);24684 const ty = try sema.getBuiltinType(name);
24891 const air_ref = try sema.resolveInst(zir_ref);24685 const air_ref = try sema.resolveInst(zir_ref);
24892 const coerced = try sema.coerce(block, ty, air_ref, src);24686 const coerced = try sema.coerce(block, ty, air_ref, src);
24893 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);24687 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
...@@ -25656,7 +25450,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -25656,7 +25450,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
25656 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;25450 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
25657 const func = try sema.resolveInst(extra.callee);25451 const func = try sema.resolveInst(extra.callee);
2565825452
25659 const modifier_ty = try pt.getBuiltinType("CallModifier");25453 const modifier_ty = try sema.getBuiltinType("CallModifier");
25660 const air_ref = try sema.resolveInst(extra.modifier);25454 const air_ref = try sema.resolveInst(extra.modifier);
25661 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);25455 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
25662 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{25456 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{
...@@ -26782,7 +26576,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26782,7 +26576,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26782 const body = sema.code.bodySlice(extra_index, body_len);26576 const body = sema.code.bodySlice(extra_index, body_len);
26783 extra_index += body.len;26577 extra_index += body.len;
2678426578
26785 const addrspace_ty = try pt.getBuiltinType("AddressSpace");26579 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
26786 const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{26580 const val = try sema.resolveGenericBody(block, addrspace_src, body, inst, addrspace_ty, .{
26787 .needed_comptime_reason = "addrspace must be comptime-known",26581 .needed_comptime_reason = "addrspace must be comptime-known",
26788 });26582 });
...@@ -26793,7 +26587,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26793,7 +26587,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26793 } else if (extra.data.bits.has_addrspace_ref) blk: {26587 } else if (extra.data.bits.has_addrspace_ref) blk: {
26794 const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);26588 const addrspace_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
26795 extra_index += 1;26589 extra_index += 1;
26796 const addrspace_ty = try pt.getBuiltinType("AddressSpace");26590 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
26797 const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) {26591 const uncoerced_addrspace = sema.resolveInst(addrspace_ref) catch |err| switch (err) {
26798 error.GenericPoison => break :blk null,26592 error.GenericPoison => break :blk null,
26799 else => |e| return e,26593 else => |e| return e,
...@@ -26847,7 +26641,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26847,7 +26641,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26847 const body = sema.code.bodySlice(extra_index, body_len);26641 const body = sema.code.bodySlice(extra_index, body_len);
26848 extra_index += body.len;26642 extra_index += body.len;
2684926643
26850 const cc_ty = try pt.getBuiltinType("CallingConvention");26644 const cc_ty = try sema.getBuiltinType("CallingConvention");
26851 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{26645 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{
26852 .needed_comptime_reason = "calling convention must be comptime-known",26646 .needed_comptime_reason = "calling convention must be comptime-known",
26853 });26647 });
...@@ -26858,7 +26652,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -26858,7 +26652,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
26858 } else if (extra.data.bits.has_cc_ref) blk: {26652 } else if (extra.data.bits.has_cc_ref) blk: {
26859 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);26653 const cc_ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_index]);
26860 extra_index += 1;26654 extra_index += 1;
26861 const cc_ty = try pt.getBuiltinType("CallingConvention");26655 const cc_ty = try sema.getBuiltinType("CallingConvention");
26862 const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) {26656 const uncoerced_cc = sema.resolveInst(cc_ref) catch |err| switch (err) {
26863 error.GenericPoison => break :blk null,26657 error.GenericPoison => break :blk null,
26864 else => |e| return e,26658 else => |e| return e,
...@@ -27075,7 +26869,7 @@ fn resolvePrefetchOptions(...@@ -27075,7 +26869,7 @@ fn resolvePrefetchOptions(
27075 const zcu = pt.zcu;26869 const zcu = pt.zcu;
27076 const gpa = sema.gpa;26870 const gpa = sema.gpa;
27077 const ip = &zcu.intern_pool;26871 const ip = &zcu.intern_pool;
27078 const options_ty = try pt.getBuiltinType("PrefetchOptions");26872 const options_ty = try sema.getBuiltinType("PrefetchOptions");
27079 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);26873 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2708026874
27081 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });26875 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -27148,7 +26942,7 @@ fn resolveExternOptions(...@@ -27148,7 +26942,7 @@ fn resolveExternOptions(
27148 const gpa = sema.gpa;26942 const gpa = sema.gpa;
27149 const ip = &zcu.intern_pool;26943 const ip = &zcu.intern_pool;
27150 const options_inst = try sema.resolveInst(zir_ref);26944 const options_inst = try sema.resolveInst(zir_ref);
27151 const extern_options_ty = try pt.getBuiltinType("ExternOptions");26945 const extern_options_ty = try sema.getBuiltinType("ExternOptions");
27152 const options = try sema.coerce(block, extern_options_ty, options_inst, src);26946 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2715326947
27154 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });26948 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -27335,7 +27129,7 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr...@@ -27335,7 +27129,7 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr
2733527129
27336 // Values are handled here.27130 // Values are handled here.
27337 .calling_convention_c => {27131 .calling_convention_c => {
27338 const callconv_ty = try pt.getBuiltinType("CallingConvention");27132 const callconv_ty = try sema.getBuiltinType("CallingConvention");
27339 comptime assert(@intFromEnum(std.builtin.CallingConvention.C) == 1);27133 comptime assert(@intFromEnum(std.builtin.CallingConvention.C) == 1);
27340 const val = try pt.intern(.{ .enum_tag = .{27134 const val = try pt.intern(.{ .enum_tag = .{
27341 .ty = callconv_ty.toIntern(),27135 .ty = callconv_ty.toIntern(),
...@@ -27344,7 +27138,7 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr...@@ -27344,7 +27138,7 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr
27344 return Air.internedToRef(val);27138 return Air.internedToRef(val);
27345 },27139 },
27346 .calling_convention_inline => {27140 .calling_convention_inline => {
27347 const callconv_ty = try pt.getBuiltinType("CallingConvention");27141 const callconv_ty = try sema.getBuiltinType("CallingConvention");
27348 comptime assert(@intFromEnum(std.builtin.CallingConvention.Inline) == 4);27142 comptime assert(@intFromEnum(std.builtin.CallingConvention.Inline) == 4);
27349 const val = try pt.intern(.{ .enum_tag = .{27143 const val = try pt.intern(.{ .enum_tag = .{
27350 .ty = callconv_ty.toIntern(),27144 .ty = callconv_ty.toIntern(),
...@@ -27353,7 +27147,7 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr...@@ -27353,7 +27147,7 @@ fn zirBuiltinValue(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileErr
27353 return Air.internedToRef(val);27147 return Air.internedToRef(val);
27354 },27148 },
27355 };27149 };
27356 const ty = try pt.getBuiltinType(type_name);27150 const ty = try sema.getBuiltinType(type_name);
27357 return Air.internedToRef(ty.toIntern());27151 return Air.internedToRef(ty.toIntern());
27358}27152}
2735927153
...@@ -27392,7 +27186,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat...@@ -27392,7 +27186,7 @@ fn zirBranchHint(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat
27392 const uncoerced_hint = try sema.resolveInst(extra.operand);27186 const uncoerced_hint = try sema.resolveInst(extra.operand);
27393 const operand_src = block.builtinCallArgSrc(extra.node, 0);27187 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2739427188
27395 const hint_ty = try pt.getBuiltinType("BranchHint");27189 const hint_ty = try sema.getBuiltinType("BranchHint");
27396 const coerced_hint = try sema.coerce(block, hint_ty, uncoerced_hint, operand_src);27190 const coerced_hint = try sema.coerce(block, hint_ty, uncoerced_hint, operand_src);
27397 const hint_val = try sema.resolveConstDefinedValue(block, operand_src, coerced_hint, .{27191 const hint_val = try sema.resolveConstDefinedValue(block, operand_src, coerced_hint, .{
27398 .needed_comptime_reason = "operand to '@branchHint' must be comptime-known",27192 .needed_comptime_reason = "operand to '@branchHint' must be comptime-known",
...@@ -27845,18 +27639,14 @@ fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {...@@ -27845,18 +27639,14 @@ fn prepareSimplePanic(sema: *Sema, block: *Block, src: LazySrcLoc) !void {
27845 const zcu = pt.zcu;27639 const zcu = pt.zcu;
2784627640
27847 if (zcu.panic_func_index == .none) {27641 if (zcu.panic_func_index == .none) {
27848 const fn_ref = try sema.analyzeNavVal(block, src, try pt.getBuiltinNav("panic"));27642 zcu.panic_func_index = try sema.getPanicInnerFn(block, src, "call");
27849 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{27643 // Here, function body analysis must be queued up so that backends can
27850 .needed_comptime_reason = "panic handler must be comptime-known",27644 // make calls to this function.
27851 });27645 try zcu.ensureFuncBodyAnalysisQueued(zcu.panic_func_index);
27852 assert(fn_val.typeOf(zcu).zigTypeTag(zcu) == .@"fn");
27853 assert(try fn_val.typeOf(zcu).fnHasRuntimeBitsSema(pt));
27854 try zcu.ensureFuncBodyAnalysisQueued(fn_val.toIntern());
27855 zcu.panic_func_index = fn_val.toIntern();
27856 }27646 }
2785727647
27858 if (zcu.null_stack_trace == .none) {27648 if (zcu.null_stack_trace == .none) {
27859 const stack_trace_ty = try pt.getBuiltinType("StackTrace");27649 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
27860 try stack_trace_ty.resolveFields(pt);27650 try stack_trace_ty.resolveFields(pt);
27861 const target = zcu.getTarget();27651 const target = zcu.getTarget();
27862 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{27652 const ptr_stack_trace_ty = try pt.ptrTypeSema(.{
...@@ -27884,14 +27674,15 @@ fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.Pan...@@ -27884,14 +27674,15 @@ fn preparePanicId(sema: *Sema, block: *Block, src: LazySrcLoc, panic_id: Zcu.Pan
2788427674
27885 try sema.prepareSimplePanic(block, src);27675 try sema.prepareSimplePanic(block, src);
2788627676
27887 const panic_messages_ty = try pt.getBuiltinType("panic_messages");27677 const panic_ty = try sema.getBuiltinType("Panic");
27678 const panic_messages_ty = try sema.getBuiltinInnerType(block, src, panic_ty, "Panic", "messages");
27888 const msg_nav_index = (sema.namespaceLookup(27679 const msg_nav_index = (sema.namespaceLookup(
27889 block,27680 block,
27890 LazySrcLoc.unneeded,27681 LazySrcLoc.unneeded,
27891 panic_messages_ty.getNamespaceIndex(zcu),27682 panic_messages_ty.getNamespaceIndex(zcu),
27892 try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),27683 try zcu.intern_pool.getOrPutString(gpa, pt.tid, @tagName(panic_id), .no_embedded_nulls),
27893 ) catch |err| switch (err) {27684 ) catch |err| switch (err) {
27894 error.AnalysisFail => @panic("std.builtin.panic_messages is corrupt"),27685 error.AnalysisFail => return error.AnalysisFail,
27895 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,27686 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
27896 error.OutOfMemory => |e| return e,27687 error.OutOfMemory => |e| return e,
27897 }).?;27688 }).?;
...@@ -28015,7 +27806,7 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -28015,7 +27806,7 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
28015 try sema.callBuiltin(block, src, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr }, operation);27806 try sema.callBuiltin(block, src, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr }, operation);
28016}27807}
2801727808
28018fn panicUnwrapError(27809fn addSafetyCheckUnwrapError(
28019 sema: *Sema,27810 sema: *Sema,
28020 parent_block: *Block,27811 parent_block: *Block,
28021 src: LazySrcLoc,27812 src: LazySrcLoc,
...@@ -28023,12 +27814,8 @@ fn panicUnwrapError(...@@ -28023,12 +27814,8 @@ fn panicUnwrapError(
28023 unwrap_err_tag: Air.Inst.Tag,27814 unwrap_err_tag: Air.Inst.Tag,
28024 is_non_err_tag: Air.Inst.Tag,27815 is_non_err_tag: Air.Inst.Tag,
28025) !void {27816) !void {
28026 const pt = sema.pt;
28027 assert(!parent_block.is_comptime);27817 assert(!parent_block.is_comptime);
28028 const ok = try parent_block.addUnOp(is_non_err_tag, operand);27818 const ok = try parent_block.addUnOp(is_non_err_tag, operand);
28029 if (!pt.zcu.comp.formatted_panics) {
28030 return sema.addSafetyCheck(parent_block, src, ok, .unwrap_error);
28031 }
28032 const gpa = sema.gpa;27819 const gpa = sema.gpa;
2803327820
28034 var fail_block: Block = .{27821 var fail_block: Block = .{
...@@ -28044,21 +27831,26 @@ fn panicUnwrapError(...@@ -28044,21 +27831,26 @@ fn panicUnwrapError(
2804427831
28045 defer fail_block.instructions.deinit(gpa);27832 defer fail_block.instructions.deinit(gpa);
2804627833
28047 {27834 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
28048 if (!pt.zcu.backendSupportsFeature(.panic_unwrap_error)) {27835 try safetyPanicUnwrapError(sema, &fail_block, src, err);
28049 _ = try fail_block.addNoOp(.trap);27836
28050 } else {
28051 const panic_fn = try sema.pt.getBuiltin("panicUnwrapError");
28052 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
28053 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
28054 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
28055 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, &args, .@"safety check");
28056 }
28057 }
28058 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);27837 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
28059}27838}
2806027839
28061fn panicIndexOutOfBounds(27840fn safetyPanicUnwrapError(sema: *Sema, block: *Block, src: LazySrcLoc, err: Air.Inst.Ref) !void {
27841 const pt = sema.pt;
27842 const zcu = pt.zcu;
27843 if (!zcu.backendSupportsFeature(.panic_fn)) {
27844 _ = try block.addNoOp(.trap);
27845 } else {
27846 const panic_fn = try getPanicInnerFn(sema, block, src, "unwrapError");
27847 const err_return_trace = try sema.getErrorReturnTrace(block);
27848 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
27849 try sema.callBuiltin(block, src, Air.internedToRef(panic_fn), .auto, &args, .@"safety check");
27850 }
27851}
27852
27853fn addSafetyCheckIndexOob(
28062 sema: *Sema,27854 sema: *Sema,
28063 parent_block: *Block,27855 parent_block: *Block,
28064 src: LazySrcLoc,27856 src: LazySrcLoc,
...@@ -28068,13 +27860,10 @@ fn panicIndexOutOfBounds(...@@ -28068,13 +27860,10 @@ fn panicIndexOutOfBounds(
28068) !void {27860) !void {
28069 assert(!parent_block.is_comptime);27861 assert(!parent_block.is_comptime);
28070 const ok = try parent_block.addBinOp(cmp_op, index, len);27862 const ok = try parent_block.addBinOp(cmp_op, index, len);
28071 if (!sema.pt.zcu.comp.formatted_panics) {27863 return addSafetyCheckCall(sema, parent_block, src, ok, "outOfBounds", &.{ index, len });
28072 return sema.addSafetyCheck(parent_block, src, ok, .index_out_of_bounds);
28073 }
28074 try sema.safetyCheckFormatted(parent_block, src, ok, "panicOutOfBounds", &.{ index, len });
28075}27864}
2807627865
28077fn panicInactiveUnionField(27866fn addSafetyCheckInactiveUnionField(
28078 sema: *Sema,27867 sema: *Sema,
28079 parent_block: *Block,27868 parent_block: *Block,
28080 src: LazySrcLoc,27869 src: LazySrcLoc,
...@@ -28083,13 +27872,10 @@ fn panicInactiveUnionField(...@@ -28083,13 +27872,10 @@ fn panicInactiveUnionField(
28083) !void {27872) !void {
28084 assert(!parent_block.is_comptime);27873 assert(!parent_block.is_comptime);
28085 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);27874 const ok = try parent_block.addBinOp(.cmp_eq, active_tag, wanted_tag);
28086 if (!sema.pt.zcu.comp.formatted_panics) {27875 return addSafetyCheckCall(sema, parent_block, src, ok, "inactiveUnionField", &.{ active_tag, wanted_tag });
28087 return sema.addSafetyCheck(parent_block, src, ok, .inactive_union_field);
28088 }
28089 try sema.safetyCheckFormatted(parent_block, src, ok, "panicInactiveUnionField", &.{ active_tag, wanted_tag });
28090}27876}
2809127877
28092fn panicSentinelMismatch(27878fn addSafetyCheckSentinelMismatch(
28093 sema: *Sema,27879 sema: *Sema,
28094 parent_block: *Block,27880 parent_block: *Block,
28095 src: LazySrcLoc,27881 src: LazySrcLoc,
...@@ -28114,8 +27900,7 @@ fn panicSentinelMismatch(...@@ -28114,8 +27900,7 @@ fn panicSentinelMismatch(
28114 };27900 };
2811527901
28116 const ok = if (sentinel_ty.zigTypeTag(zcu) == .vector) ok: {27902 const ok = if (sentinel_ty.zigTypeTag(zcu) == .vector) ok: {
28117 const eql =27903 const eql = try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
28118 try parent_block.addCmpVector(expected_sentinel, actual_sentinel, .eq);
28119 break :ok try parent_block.addInst(.{27904 break :ok try parent_block.addInst(.{
28120 .tag = .reduce,27905 .tag = .reduce,
28121 .data = .{ .reduce = .{27906 .data = .{ .reduce = .{
...@@ -28128,24 +27913,23 @@ fn panicSentinelMismatch(...@@ -28128,24 +27913,23 @@ fn panicSentinelMismatch(
28128 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);27913 break :ok try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel);
28129 };27914 };
2813027915
28131 if (!pt.zcu.comp.formatted_panics) {27916 return addSafetyCheckCall(sema, parent_block, src, ok, "sentinelMismatch", &.{
28132 return sema.addSafetyCheck(parent_block, src, ok, .sentinel_mismatch);27917 expected_sentinel, actual_sentinel,
28133 }27918 });
28134 try sema.safetyCheckFormatted(parent_block, src, ok, "panicSentinelMismatch", &.{ expected_sentinel, actual_sentinel });
28135}27919}
2813627920
28137fn safetyCheckFormatted(27921fn addSafetyCheckCall(
28138 sema: *Sema,27922 sema: *Sema,
28139 parent_block: *Block,27923 parent_block: *Block,
28140 src: LazySrcLoc,27924 src: LazySrcLoc,
28141 ok: Air.Inst.Ref,27925 ok: Air.Inst.Ref,
28142 func: []const u8,27926 func_name: []const u8,
28143 args: []const Air.Inst.Ref,27927 args: []const Air.Inst.Ref,
28144) CompileError!void {27928) !void {
27929 assert(!parent_block.is_comptime);
27930 const gpa = sema.gpa;
28145 const pt = sema.pt;27931 const pt = sema.pt;
28146 const zcu = pt.zcu;27932 const zcu = pt.zcu;
28147 assert(zcu.comp.formatted_panics);
28148 const gpa = sema.gpa;
2814927933
28150 var fail_block: Block = .{27934 var fail_block: Block = .{
28151 .parent = parent_block,27935 .parent = parent_block,
...@@ -28160,12 +27944,13 @@ fn safetyCheckFormatted(...@@ -28160,12 +27944,13 @@ fn safetyCheckFormatted(
2816027944
28161 defer fail_block.instructions.deinit(gpa);27945 defer fail_block.instructions.deinit(gpa);
2816227946
28163 if (!zcu.backendSupportsFeature(.safety_check_formatted)) {27947 if (!zcu.backendSupportsFeature(.panic_fn)) {
28164 _ = try fail_block.addNoOp(.trap);27948 _ = try fail_block.addNoOp(.trap);
28165 } else {27949 } else {
28166 const panic_fn = try pt.getBuiltin(func);27950 const panic_fn = try getPanicInnerFn(sema, &fail_block, src, func_name);
28167 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");27951 try sema.callBuiltin(&fail_block, src, Air.internedToRef(panic_fn), .auto, args, .@"safety check");
28168 }27952 }
27953
28169 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);27954 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
28170}27955}
2817127956
...@@ -29229,7 +29014,7 @@ fn unionFieldPtr(...@@ -29229,7 +29014,7 @@ fn unionFieldPtr(
29229 // TODO would it be better if get_union_tag supported pointers to unions?29014 // TODO would it be better if get_union_tag supported pointers to unions?
29230 const union_val = try block.addTyOp(.load, union_ty, union_ptr);29015 const union_val = try block.addTyOp(.load, union_ty, union_ptr);
29231 const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_val);29016 const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_val);
29232 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);29017 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag);
29233 }29018 }
29234 if (field_ty.zigTypeTag(zcu) == .noreturn) {29019 if (field_ty.zigTypeTag(zcu) == .noreturn) {
29235 _ = try block.addNoOp(.unreach);29020 _ = try block.addNoOp(.unreach);
...@@ -29304,7 +29089,7 @@ fn unionFieldVal(...@@ -29304,7 +29089,7 @@ fn unionFieldVal(
29304 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);29089 const wanted_tag_val = try pt.enumValueFieldIndex(Type.fromInterned(union_obj.enum_tag_ty), enum_field_index);
29305 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());29090 const wanted_tag = Air.internedToRef(wanted_tag_val.toIntern());
29306 const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval);29091 const active_tag = try block.addTyOp(.get_union_tag, Type.fromInterned(union_obj.enum_tag_ty), union_byval);
29307 try sema.panicInactiveUnionField(block, src, active_tag, wanted_tag);29092 try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, wanted_tag);
29308 }29093 }
29309 if (field_ty.zigTypeTag(zcu) == .noreturn) {29094 if (field_ty.zigTypeTag(zcu) == .noreturn) {
29310 _ = try block.addNoOp(.unreach);29095 _ = try block.addNoOp(.unreach);
...@@ -29668,11 +29453,11 @@ fn elemValArray(...@@ -29668,11 +29453,11 @@ fn elemValArray(
2966829453
29669 const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src;29454 const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src;
29670 if (oob_safety and block.wantSafety()) {29455 if (oob_safety and block.wantSafety()) {
29671 // Runtime check is only needed if unable to comptime check29456 // Runtime check is only needed if unable to comptime check.
29672 if (maybe_index_val == null) {29457 if (maybe_index_val == null) {
29673 const len_inst = try pt.intRef(Type.usize, array_len);29458 const len_inst = try pt.intRef(Type.usize, array_len);
29674 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;29459 const cmp_op: Air.Inst.Tag = if (array_sent != null) .cmp_lte else .cmp_lt;
29675 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);29460 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
29676 }29461 }
29677 }29462 }
2967829463
...@@ -29740,7 +29525,7 @@ fn elemPtrArray(...@@ -29740,7 +29525,7 @@ fn elemPtrArray(
29740 if (oob_safety and block.wantSafety() and offset == null) {29525 if (oob_safety and block.wantSafety() and offset == null) {
29741 const len_inst = try pt.intRef(Type.usize, array_len);29526 const len_inst = try pt.intRef(Type.usize, array_len);
29742 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;29527 const cmp_op: Air.Inst.Tag = if (array_sent) .cmp_lte else .cmp_lt;
29743 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);29528 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
29744 }29529 }
2974529530
29746 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);29531 return block.addPtrElemPtr(array_ptr, elem_index, elem_ptr_ty);
...@@ -29799,7 +29584,7 @@ fn elemValSlice(...@@ -29799,7 +29584,7 @@ fn elemValSlice(
29799 else29584 else
29800 try block.addTyOp(.slice_len, Type.usize, slice);29585 try block.addTyOp(.slice_len, Type.usize, slice);
29801 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;29586 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
29802 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);29587 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
29803 }29588 }
29804 return block.addBinOp(.slice_elem_val, slice, elem_index);29589 return block.addBinOp(.slice_elem_val, slice, elem_index);
29805}29590}
...@@ -29859,7 +29644,7 @@ fn elemPtrSlice(...@@ -29859,7 +29644,7 @@ fn elemPtrSlice(
29859 break :len try block.addTyOp(.slice_len, Type.usize, slice);29644 break :len try block.addTyOp(.slice_len, Type.usize, slice);
29860 };29645 };
29861 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;29646 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
29862 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);29647 try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op);
29863 }29648 }
29864 return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty);29649 return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty);
29865}29650}
...@@ -32891,7 +32676,7 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {...@@ -32891,7 +32676,7 @@ fn optRefValue(sema: *Sema, opt_val: ?Value) !Value {
32891 return Value.fromInterned(try pt.intern(.{ .opt = .{32676 return Value.fromInterned(try pt.intern(.{ .opt = .{
32892 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),32677 .ty = (try pt.optionalType(ptr_anyopaque_ty.toIntern())).toIntern(),
32893 .val = if (opt_val) |val| (try pt.getCoerced(32678 .val = if (opt_val) |val| (try pt.getCoerced(
32894 Value.fromInterned(try sema.refValue(val.toIntern())),32679 Value.fromInterned(try pt.refValue(val.toIntern())),
32895 ptr_anyopaque_ty,32680 ptr_anyopaque_ty,
32896 )).toIntern() else .none,32681 )).toIntern() else .none,
32897 } }));32682 } }));
...@@ -33667,11 +33452,7 @@ fn analyzeSlice(...@@ -33667,11 +33452,7 @@ fn analyzeSlice(
33667 assert(!block.is_comptime);33452 assert(!block.is_comptime);
33668 try sema.requireRuntimeBlock(block, src, runtime_src.?);33453 try sema.requireRuntimeBlock(block, src, runtime_src.?);
33669 const ok = try block.addBinOp(.cmp_lte, start, end);33454 const ok = try block.addBinOp(.cmp_lte, start, end);
33670 if (!pt.zcu.comp.formatted_panics) {33455 try sema.addSafetyCheckCall(block, src, ok, "startGreaterThanEnd", &.{ start, end });
33671 try sema.addSafetyCheck(block, src, ok, .start_index_greater_than_end);
33672 } else {
33673 try sema.safetyCheckFormatted(block, src, ok, "panicStartGreaterThanEnd", &.{ start, end });
33674 }
33675 }33456 }
33676 const new_len = if (by_length)33457 const new_len = if (by_length)
33677 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)33458 try sema.coerce(block, Type.usize, uncasted_end_opt, end_src)
...@@ -33726,11 +33507,11 @@ fn analyzeSlice(...@@ -33726,11 +33507,11 @@ fn analyzeSlice(
33726 else33507 else
33727 end;33508 end;
3372833509
33729 try sema.panicIndexOutOfBounds(block, src, actual_end, actual_len, .cmp_lte);33510 try sema.addSafetyCheckIndexOob(block, src, actual_end, actual_len, .cmp_lte);
33730 }33511 }
3373133512
33732 // requirement: result[new_len] == slice_sentinel33513 // requirement: result[new_len] == slice_sentinel
33733 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);33514 try sema.addSafetyCheckSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
33734 }33515 }
33735 return result;33516 return result;
33736 };33517 };
...@@ -33789,11 +33570,11 @@ fn analyzeSlice(...@@ -33789,11 +33570,11 @@ fn analyzeSlice(
33789 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)33570 try sema.analyzeArithmetic(block, .add, end, .one, src, end_src, end_src, true)
33790 else33571 else
33791 end;33572 end;
33792 try sema.panicIndexOutOfBounds(block, src, actual_end, len_inst, .cmp_lte);33573 try sema.addSafetyCheckIndexOob(block, src, actual_end, len_inst, .cmp_lte);
33793 }33574 }
3379433575
33795 // requirement: start <= end33576 // requirement: start <= end
33796 try sema.panicIndexOutOfBounds(block, src, start, end, .cmp_lte);33577 try sema.addSafetyCheckIndexOob(block, src, start, end, .cmp_lte);
33797 }33578 }
33798 const result = try block.addInst(.{33579 const result = try block.addInst(.{
33799 .tag = .slice,33580 .tag = .slice,
...@@ -33807,7 +33588,7 @@ fn analyzeSlice(...@@ -33807,7 +33588,7 @@ fn analyzeSlice(
33807 });33588 });
33808 if (block.wantSafety()) {33589 if (block.wantSafety()) {
33809 // requirement: result[new_len] == slice_sentinel33590 // requirement: result[new_len] == slice_sentinel
33810 try sema.panicSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);33591 try sema.addSafetyCheckSentinelMismatch(block, src, slice_sentinel, elem_ty, result, new_len);
33811 }33592 }
33812 return result;33593 return result;
33813}33594}
...@@ -35820,7 +35601,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {...@@ -35820,7 +35601,7 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
35820 Type.fromInterned(fn_ty_info.return_type).isError(zcu))35601 Type.fromInterned(fn_ty_info.return_type).isError(zcu))
35821 {35602 {
35822 // Ensure the type exists so that backends can assume that.35603 // Ensure the type exists so that backends can assume that.
35823 _ = try pt.getBuiltinType("StackTrace");35604 _ = try sema.getBuiltinType("StackTrace");
35824 }35605 }
3582535606
35826 for (0..fn_ty_info.param_types.len) |i| {35607 for (0..fn_ty_info.param_types.len) |i| {
...@@ -37688,11 +37469,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37688,11 +37469,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37688 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);37469 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
37689 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse37470 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
37690 return null;37471 return null;
37691 const only = try pt.intern(.{ .un = .{37472 const only = try pt.internUnion(.{
37692 .ty = ty.toIntern(),37473 .ty = ty.toIntern(),
37693 .tag = tag_val.toIntern(),37474 .tag = tag_val.toIntern(),
37694 .val = val_val.toIntern(),37475 .val = val_val.toIntern(),
37695 } });37476 });
37696 return Value.fromInterned(only);37477 return Value.fromInterned(only);
37697 },37478 },
3769837479
...@@ -37866,7 +37647,7 @@ pub fn analyzeAsAddressSpace(...@@ -37866,7 +37647,7 @@ pub fn analyzeAsAddressSpace(
37866) !std.builtin.AddressSpace {37647) !std.builtin.AddressSpace {
37867 const pt = sema.pt;37648 const pt = sema.pt;
37868 const zcu = pt.zcu;37649 const zcu = pt.zcu;
37869 const addrspace_ty = try pt.getBuiltinType("AddressSpace");37650 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
37870 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);37651 const coerced = try sema.coerce(block, addrspace_ty, air_ref, src);
37871 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{37652 const addrspace_val = try sema.resolveConstDefinedValue(block, src, coerced, .{
37872 .needed_comptime_reason = "address space must be comptime-known",37653 .needed_comptime_reason = "address space must be comptime-known",
...@@ -38849,7 +38630,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check:...@@ -38849,7 +38630,7 @@ fn analyzeUnreachable(sema: *Sema, block: *Block, src: LazySrcLoc, safety_check:
38849 sema.branch_hint = .cold;38630 sema.branch_hint = .cold;
38850 }38631 }
3885138632
38852 try sema.safetyPanic(block, src, .unreach);38633 try sema.safetyPanic(block, src, .reached_unreachable);
38853 } else {38634 } else {
38854 _ = try block.addNoOp(.unreach);38635 _ = try block.addNoOp(.unreach);
38855 }38636 }
...@@ -39123,3 +38904,70 @@ const loadComptimePtr = @import("Sema/comptime_ptr_access.zig").loadComptimePtr;...@@ -39123,3 +38904,70 @@ const loadComptimePtr = @import("Sema/comptime_ptr_access.zig").loadComptimePtr;
39123const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadResult;38904const ComptimeLoadResult = @import("Sema/comptime_ptr_access.zig").ComptimeLoadResult;
39124const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;38905const storeComptimePtr = @import("Sema/comptime_ptr_access.zig").storeComptimePtr;
39125const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;38906const ComptimeStoreResult = @import("Sema/comptime_ptr_access.zig").ComptimeStoreResult;
38907
38908fn getPanicInnerFn(
38909 sema: *Sema,
38910 block: *Block,
38911 src: LazySrcLoc,
38912 inner_name: []const u8,
38913) !InternPool.Index {
38914 const gpa = sema.gpa;
38915 const pt = sema.pt;
38916 const zcu = pt.zcu;
38917 const ip = &zcu.intern_pool;
38918 const outer_ty = try sema.getBuiltinType("Panic");
38919 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38920 const opt_fn_ref = try namespaceLookupVal(sema, block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38921 const fn_ref = opt_fn_ref orelse return sema.fail(block, src, "std.builtin.Panic missing {s}", .{inner_name});
38922 const fn_val = try sema.resolveConstValue(block, src, fn_ref, .{
38923 .needed_comptime_reason = "panic handler must be comptime-known",
38924 });
38925 if (fn_val.typeOf(zcu).zigTypeTag(zcu) != .@"fn") {
38926 return sema.fail(block, src, "std.builtin.Panic.{s} is not a function", .{inner_name});
38927 }
38928 // Better not to queue up function body analysis because the function might be generic, and
38929 // the semantic analysis for the call will already queue if necessary.
38930 return fn_val.toIntern();
38931}
38932
38933fn getBuiltinType(sema: *Sema, name: []const u8) SemaError!Type {
38934 const pt = sema.pt;
38935 const ty_inst = try sema.getBuiltin(name);
38936 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
38937 try ty.resolveFully(pt);
38938 return ty;
38939}
38940
38941fn getBuiltinInnerType(
38942 sema: *Sema,
38943 block: *Block,
38944 src: LazySrcLoc,
38945 outer_ty: Type,
38946 /// Relative to "std.builtin".
38947 compile_error_parent_name: []const u8,
38948 inner_name: []const u8,
38949) !Type {
38950 const pt = sema.pt;
38951 const zcu = pt.zcu;
38952 const ip = &zcu.intern_pool;
38953 const gpa = sema.gpa;
38954 const inner_name_ip = try ip.getOrPutString(gpa, pt.tid, inner_name, .no_embedded_nulls);
38955 const opt_nav = try sema.namespaceLookup(block, src, outer_ty.getNamespaceIndex(zcu), inner_name_ip);
38956 const nav = opt_nav orelse return sema.fail(block, src, "std.builtin.{s} missing {s}", .{
38957 compile_error_parent_name, inner_name,
38958 });
38959 try sema.ensureNavResolved(src, nav);
38960 const val = Value.fromInterned(ip.getNav(nav).status.resolved.val);
38961 const ty = val.toType();
38962 try ty.resolveFully(pt);
38963 return ty;
38964}
38965
38966fn getBuiltin(sema: *Sema, name: []const u8) SemaError!Air.Inst.Ref {
38967 const pt = sema.pt;
38968 const zcu = pt.zcu;
38969 const ip = &zcu.intern_pool;
38970 const nav = try pt.getBuiltinNav(name);
38971 try pt.ensureCauAnalyzed(ip.getNav(nav).analysis_owner.unwrap().?);
38972 return Air.internedToRef(ip.getNav(nav).status.resolved.val);
38973}
src/Sema/bitcast.zig+6-6
...@@ -613,11 +613,11 @@ const PackValueBits = struct {...@@ -613,11 +613,11 @@ const PackValueBits = struct {
613 pack.bit_offset = prev_bit_offset;613 pack.bit_offset = prev_bit_offset;
614 break :backing;614 break :backing;
615 }615 }
616 return Value.fromInterned(try pt.intern(.{ .un = .{616 return Value.fromInterned(try pt.internUnion(.{
617 .ty = ty.toIntern(),617 .ty = ty.toIntern(),
618 .tag = .none,618 .tag = .none,
619 .val = backing_val.toIntern(),619 .val = backing_val.toIntern(),
620 } }));620 }));
621 }621 }
622622
623 const field_order = try pack.arena.alloc(u32, ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu));623 const field_order = try pack.arena.alloc(u32, ty.unionTagTypeHypothetical(zcu).enumFieldCount(zcu));
...@@ -658,21 +658,21 @@ const PackValueBits = struct {...@@ -658,21 +658,21 @@ const PackValueBits = struct {
658 continue;658 continue;
659 }659 }
660 const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);660 const tag_val = try pt.enumValueFieldIndex(ty.unionTagTypeHypothetical(zcu), field_idx);
661 return Value.fromInterned(try pt.intern(.{ .un = .{661 return Value.fromInterned(try pt.internUnion(.{
662 .ty = ty.toIntern(),662 .ty = ty.toIntern(),
663 .tag = tag_val.toIntern(),663 .tag = tag_val.toIntern(),
664 .val = field_val.toIntern(),664 .val = field_val.toIntern(),
665 } }));665 }));
666 }666 }
667667
668 // No field could represent the value. Just do whatever happens when we try to read668 // No field could represent the value. Just do whatever happens when we try to read
669 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.669 // the backing type - either `undefined` or `error.ReinterpretDeclRef`.
670 const backing_val = try pack.get(backing_ty);670 const backing_val = try pack.get(backing_ty);
671 return Value.fromInterned(try pt.intern(.{ .un = .{671 return Value.fromInterned(try pt.internUnion(.{
672 .ty = ty.toIntern(),672 .ty = ty.toIntern(),
673 .tag = .none,673 .tag = .none,
674 .val = backing_val.toIntern(),674 .val = backing_val.toIntern(),
675 } }));675 }));
676 },676 },
677 else => return pack.primitive(ty),677 else => return pack.primitive(ty),
678 }678 }
src/Type.zig+2-2
...@@ -2677,11 +2677,11 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {...@@ -2677,11 +2677,11 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
2677 const only_field_ty = union_obj.field_types.get(ip)[0];2677 const only_field_ty = union_obj.field_types.get(ip)[0];
2678 const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(pt)) orelse2678 const val_val = (try Type.fromInterned(only_field_ty).onePossibleValue(pt)) orelse
2679 return null;2679 return null;
2680 const only = try pt.intern(.{ .un = .{2680 const only = try pt.internUnion(.{
2681 .ty = ty.toIntern(),2681 .ty = ty.toIntern(),
2682 .tag = tag_val.toIntern(),2682 .tag = tag_val.toIntern(),
2683 .val = val_val.toIntern(),2683 .val = val_val.toIntern(),
2684 } });2684 });
2685 return Value.fromInterned(only);2685 return Value.fromInterned(only);
2686 },2686 },
2687 .opaque_type => return null,2687 .opaque_type => return null,
src/Value.zig+6-6
...@@ -713,11 +713,11 @@ pub fn readFromMemory(...@@ -713,11 +713,11 @@ pub fn readFromMemory(
713 const union_size = ty.abiSize(zcu);713 const union_size = ty.abiSize(zcu);
714 const array_ty = try zcu.arrayType(.{ .len = union_size, .child = .u8_type });714 const array_ty = try zcu.arrayType(.{ .len = union_size, .child = .u8_type });
715 const val = (try readFromMemory(array_ty, zcu, buffer, arena)).toIntern();715 const val = (try readFromMemory(array_ty, zcu, buffer, arena)).toIntern();
716 return Value.fromInterned(try pt.intern(.{ .un = .{716 return Value.fromInterned(try pt.internUnion(.{
717 .ty = ty.toIntern(),717 .ty = ty.toIntern(),
718 .tag = .none,718 .tag = .none,
719 .val = val,719 .val = val,
720 } }));720 }));
721 },721 },
722 .@"packed" => {722 .@"packed" => {
723 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;723 const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;
...@@ -860,11 +860,11 @@ pub fn readFromPackedMemory(...@@ -860,11 +860,11 @@ pub fn readFromPackedMemory(
860 .@"packed" => {860 .@"packed" => {
861 const backing_ty = try ty.unionBackingType(pt);861 const backing_ty = try ty.unionBackingType(pt);
862 const val = (try readFromPackedMemory(backing_ty, pt, buffer, bit_offset, arena)).toIntern();862 const val = (try readFromPackedMemory(backing_ty, pt, buffer, bit_offset, arena)).toIntern();
863 return Value.fromInterned(try pt.intern(.{ .un = .{863 return Value.fromInterned(try pt.internUnion(.{
864 .ty = ty.toIntern(),864 .ty = ty.toIntern(),
865 .tag = .none,865 .tag = .none,
866 .val = val,866 .val = val,
867 } }));867 }));
868 },868 },
869 },869 },
870 .pointer => {870 .pointer => {
...@@ -4481,11 +4481,11 @@ pub fn resolveLazy(...@@ -4481,11 +4481,11 @@ pub fn resolveLazy(
4481 return if (resolved_tag == un.tag and resolved_val == un.val)4481 return if (resolved_tag == un.tag and resolved_val == un.val)
4482 val4482 val
4483 else4483 else
4484 Value.fromInterned(try pt.intern(.{ .un = .{4484 Value.fromInterned(try pt.internUnion(.{
4485 .ty = un.ty,4485 .ty = un.ty,
4486 .tag = resolved_tag,4486 .tag = resolved_tag,
4487 .val = resolved_val,4487 .val = resolved_val,
4488 } }));4488 }));
4489 },4489 },
4490 else => return val,4490 else => return val,
4491 }4491 }
src/Zcu.zig+4-16
...@@ -220,7 +220,7 @@ generation: u32 = 0,...@@ -220,7 +220,7 @@ generation: u32 = 0,
220pub const PerThread = @import("Zcu/PerThread.zig");220pub const PerThread = @import("Zcu/PerThread.zig");
221221
222pub const PanicId = enum {222pub const PanicId = enum {
223 unreach,223 reached_unreachable,
224 unwrap_null,224 unwrap_null,
225 cast_to_null,225 cast_to_null,
226 incorrect_alignment,226 incorrect_alignment,
...@@ -232,15 +232,10 @@ pub const PanicId = enum {...@@ -232,15 +232,10 @@ pub const PanicId = enum {
232 shr_overflow,232 shr_overflow,
233 divide_by_zero,233 divide_by_zero,
234 exact_division_remainder,234 exact_division_remainder,
235 inactive_union_field,
236 integer_part_out_of_bounds,235 integer_part_out_of_bounds,
237 corrupt_switch,236 corrupt_switch,
238 shift_rhs_too_big,237 shift_rhs_too_big,
239 invalid_enum_value,238 invalid_enum_value,
240 sentinel_mismatch,
241 unwrap_error,
242 index_out_of_bounds,
243 start_index_greater_than_end,
244 for_len_mismatch,239 for_len_mismatch,
245 memcpy_len_mismatch,240 memcpy_len_mismatch,
246 memcpy_alias,241 memcpy_alias,
...@@ -2923,17 +2918,10 @@ pub fn addGlobalAssembly(zcu: *Zcu, cau: InternPool.Cau.Index, source: []const u...@@ -2923,17 +2918,10 @@ pub fn addGlobalAssembly(zcu: *Zcu, cau: InternPool.Cau.Index, source: []const u
2923}2918}
29242919
2925pub const Feature = enum {2920pub const Feature = enum {
2926 /// When this feature is enabled, Sema will emit calls to `std.builtin.panic`2921 /// When this feature is enabled, Sema will emit calls to
2927 /// for things like safety checks and unreachables. Otherwise traps will be emitted.2922 /// `std.builtin.Panic` functions for things like safety checks and
2923 /// unreachables. Otherwise traps will be emitted.
2928 panic_fn,2924 panic_fn,
2929 /// When this feature is enabled, Sema will emit calls to `std.builtin.panicUnwrapError`.
2930 /// This error message requires more advanced formatting, hence it being seperate from `panic_fn`.
2931 /// Otherwise traps will be emitted.
2932 panic_unwrap_error,
2933 /// When this feature is enabled, Sema will emit calls to the more complex panic functions
2934 /// that use formatting to add detail to error messages. Similar to `panic_unwrap_error`.
2935 /// Otherwise traps will be emitted.
2936 safety_check_formatted,
2937 /// When this feature is enabled, Sema will insert tracer functions for gathering a stack2925 /// When this feature is enabled, Sema will insert tracer functions for gathering a stack
2938 /// trace for error returns.2926 /// trace for error returns.
2939 error_return_trace,2927 error_return_trace,
src/Zcu/PerThread.zig+53-43
...@@ -1,6 +1,32 @@...@@ -1,6 +1,32 @@
1//! This type provides a wrapper around a `*Zcu` for uses which require a thread `Id`.1//! This type provides a wrapper around a `*Zcu` for uses which require a thread `Id`.
2//! Any operation which mutates `InternPool` state lives here rather than on `Zcu`.2//! Any operation which mutates `InternPool` state lives here rather than on `Zcu`.
33
4const Air = @import("../Air.zig");
5const Allocator = std.mem.Allocator;
6const assert = std.debug.assert;
7const Ast = std.zig.Ast;
8const AstGen = std.zig.AstGen;
9const BigIntConst = std.math.big.int.Const;
10const BigIntMutable = std.math.big.int.Mutable;
11const build_options = @import("build_options");
12const builtin = @import("builtin");
13const Cache = std.Build.Cache;
14const dev = @import("../dev.zig");
15const InternPool = @import("../InternPool.zig");
16const AnalUnit = InternPool.AnalUnit;
17const isUpDir = @import("../introspect.zig").isUpDir;
18const Liveness = @import("../Liveness.zig");
19const log = std.log.scoped(.zcu);
20const Module = @import("../Package.zig").Module;
21const Sema = @import("../Sema.zig");
22const std = @import("std");
23const target_util = @import("../target.zig");
24const trace = @import("../tracy.zig").trace;
25const Type = @import("../Type.zig");
26const Value = @import("../Value.zig");
27const Zcu = @import("../Zcu.zig");
28const Zir = std.zig.Zir;
29
4zcu: *Zcu,30zcu: *Zcu,
531
6/// Dense, per-thread unique index.32/// Dense, per-thread unique index.
...@@ -2697,11 +2723,16 @@ pub fn reportRetryableFileError(...@@ -2697,11 +2723,16 @@ pub fn reportRetryableFileError(
2697 gop.value_ptr.* = err_msg;2723 gop.value_ptr.* = err_msg;
2698}2724}
26992725
2700///Shortcut for calling `intern_pool.get`.2726/// Shortcut for calling `intern_pool.get`.
2701pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {2727pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {
2702 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);2728 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
2703}2729}
27042730
2731/// Shortcut for calling `intern_pool.getUnion`.
2732pub fn internUnion(pt: Zcu.PerThread, un: InternPool.Key.Union) Allocator.Error!InternPool.Index {
2733 return pt.zcu.intern_pool.getUnion(pt.zcu.gpa, pt.tid, un);
2734}
2735
2705/// Essentially a shortcut for calling `intern_pool.getCoerced`.2736/// Essentially a shortcut for calling `intern_pool.getCoerced`.
2706/// However, this function also allows coercing `extern`s. The `InternPool` function can't do2737/// However, this function also allows coercing `extern`s. The `InternPool` function can't do
2707/// this because it requires potentially pushing to the job queue.2738/// this because it requires potentially pushing to the job queue.
...@@ -2949,11 +2980,12 @@ pub fn intValue_i64(pt: Zcu.PerThread, ty: Type, x: i64) Allocator.Error!Value {...@@ -2949,11 +2980,12 @@ pub fn intValue_i64(pt: Zcu.PerThread, ty: Type, x: i64) Allocator.Error!Value {
2949}2980}
29502981
2951pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value {2982pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) Allocator.Error!Value {
2952 return Value.fromInterned(try pt.intern(.{ .un = .{2983 const zcu = pt.zcu;
2984 return Value.fromInterned(try zcu.intern_pool.getUnion(zcu.gpa, pt.tid, .{
2953 .ty = union_ty.toIntern(),2985 .ty = union_ty.toIntern(),
2954 .tag = tag.toIntern(),2986 .tag = tag.toIntern(),
2955 .val = val.toIntern(),2987 .val = val.toIntern(),
2956 } }));2988 }));
2957}2989}
29582990
2959/// This function casts the float representation down to the representation of the type, potentially2991/// This function casts the float representation down to the representation of the type, potentially
...@@ -3069,14 +3101,6 @@ pub fn structPackedFieldBitOffset(...@@ -3069,14 +3101,6 @@ pub fn structPackedFieldBitOffset(
3069 unreachable; // index out of bounds3101 unreachable; // index out of bounds
3070}3102}
30713103
3072pub fn getBuiltin(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Air.Inst.Ref {
3073 const zcu = pt.zcu;
3074 const ip = &zcu.intern_pool;
3075 const nav = try pt.getBuiltinNav(name);
3076 pt.ensureCauAnalyzed(ip.getNav(nav).analysis_owner.unwrap().?) catch @panic("std.builtin is corrupt");
3077 return Air.internedToRef(ip.getNav(nav).status.resolved.val);
3078}
3079
3080pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {3104pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!InternPool.Nav.Index {
3081 const zcu = pt.zcu;3105 const zcu = pt.zcu;
3082 const gpa = zcu.gpa;3106 const gpa = zcu.gpa;
...@@ -3094,13 +3118,6 @@ pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Intern...@@ -3094,13 +3118,6 @@ pub fn getBuiltinNav(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Intern
3094 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");3118 return builtin_namespace.pub_decls.getKeyAdapted(name_str, Zcu.Namespace.NameAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
3095}3119}
30963120
3097pub fn getBuiltinType(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Type {
3098 const ty_inst = try pt.getBuiltin(name);
3099 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
3100 ty.resolveFully(pt) catch @panic("std.builtin is corrupt");
3101 return ty;
3102}
3103
3104pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator.Error!Type {3121pub fn navPtrType(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Allocator.Error!Type {
3105 const zcu = pt.zcu;3122 const zcu = pt.zcu;
3106 const ip = &zcu.intern_pool;3123 const ip = &zcu.intern_pool;
...@@ -3650,28 +3667,21 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace...@@ -3650,28 +3667,21 @@ pub fn ensureNamespaceUpToDate(pt: Zcu.PerThread, namespace_index: Zcu.Namespace
3650 namespace.generation = zcu.generation;3667 namespace.generation = zcu.generation;
3651}3668}
36523669
3653const Air = @import("../Air.zig");3670pub fn refValue(pt: Zcu.PerThread, val: InternPool.Index) Zcu.SemaError!InternPool.Index {
3654const Allocator = std.mem.Allocator;3671 const ptr_ty = (try pt.ptrTypeSema(.{
3655const assert = std.debug.assert;3672 .child = pt.zcu.intern_pool.typeOf(val),
3656const Ast = std.zig.Ast;3673 .flags = .{
3657const AstGen = std.zig.AstGen;3674 .alignment = .none,
3658const BigIntConst = std.math.big.int.Const;3675 .is_const = true,
3659const BigIntMutable = std.math.big.int.Mutable;3676 .address_space = .generic,
3660const build_options = @import("build_options");3677 },
3661const builtin = @import("builtin");3678 })).toIntern();
3662const Cache = std.Build.Cache;3679 return pt.intern(.{ .ptr = .{
3663const dev = @import("../dev.zig");3680 .ty = ptr_ty,
3664const InternPool = @import("../InternPool.zig");3681 .base_addr = .{ .uav = .{
3665const AnalUnit = InternPool.AnalUnit;3682 .val = val,
3666const isUpDir = @import("../introspect.zig").isUpDir;3683 .orig_ty = ptr_ty,
3667const Liveness = @import("../Liveness.zig");3684 } },
3668const log = std.log.scoped(.zcu);3685 .byte_offset = 0,
3669const Module = @import("../Package.zig").Module;3686 } });
3670const Sema = @import("../Sema.zig");3687}
3671const std = @import("std");
3672const target_util = @import("../target.zig");
3673const trace = @import("../tracy.zig").trace;
3674const Type = @import("../Type.zig");
3675const Value = @import("../Value.zig");
3676const Zcu = @import("../Zcu.zig");
3677const Zir = std.zig.Zir;
src/codegen/llvm.zig+7-7
...@@ -3848,13 +3848,13 @@ pub const Object = struct {...@@ -3848,13 +3848,13 @@ pub const Object = struct {
38483848
3849 .undef => unreachable, // handled above3849 .undef => unreachable, // handled above
3850 .simple_value => |simple_value| switch (simple_value) {3850 .simple_value => |simple_value| switch (simple_value) {
3851 .undefined,3851 .undefined => unreachable, // non-runtime value
3852 .void,3852 .void => unreachable, // non-runtime value
3853 .null,3853 .null => unreachable, // non-runtime value
3854 .empty_struct,3854 .empty_struct => unreachable, // non-runtime value
3855 .@"unreachable",3855 .@"unreachable" => unreachable, // non-runtime value
3856 .generic_poison,3856 .generic_poison => unreachable, // non-runtime value
3857 => unreachable, // non-runtime values3857
3858 .false => .false,3858 .false => .false,
3859 .true => .true,3859 .true => .true,
3860 },3860 },
src/crash_report.zig+15-6
...@@ -13,11 +13,23 @@ const Sema = @import("Sema.zig");...@@ -13,11 +13,23 @@ const Sema = @import("Sema.zig");
13const InternPool = @import("InternPool.zig");13const InternPool = @import("InternPool.zig");
14const Zir = std.zig.Zir;14const Zir = std.zig.Zir;
15const Decl = Zcu.Decl;15const Decl = Zcu.Decl;
16const dev = @import("dev.zig");
1617
17/// To use these crash report diagnostics, publish this panic in your main file18/// To use these crash report diagnostics, publish this panic in your main file
18/// and add `pub const enable_segfault_handler = false;` to your `std_options`.19/// and add `pub const enable_segfault_handler = false;` to your `std_options`.
19/// You will also need to call initialize() on startup, preferably as the very first operation in your program.20/// You will also need to call initialize() on startup, preferably as the very first operation in your program.
20pub const panic = if (build_options.enable_debug_extensions) compilerPanic else std.builtin.default_panic;21pub const Panic = if (build_options.enable_debug_extensions) struct {
22 pub const call = compilerPanic;
23 pub const sentinelMismatch = std.debug.FormattedPanic.sentinelMismatch;
24 pub const unwrapError = std.debug.FormattedPanic.unwrapError;
25 pub const outOfBounds = std.debug.FormattedPanic.outOfBounds;
26 pub const startGreaterThanEnd = std.debug.FormattedPanic.startGreaterThanEnd;
27 pub const inactiveUnionField = std.debug.FormattedPanic.inactiveUnionField;
28 pub const messages = std.debug.FormattedPanic.messages;
29} else if (dev.env == .bootstrap)
30 std.debug.SimplePanic
31else
32 std.debug.FormattedPanic;
2133
22/// Install signal handlers to identify crashes and report diagnostics.34/// Install signal handlers to identify crashes and report diagnostics.
23pub fn initialize() void {35pub fn initialize() void {
...@@ -317,9 +329,6 @@ const PanicSwitch = struct {...@@ -317,9 +329,6 @@ const PanicSwitch = struct {
317 /// until all panicking threads have dumped their traces.329 /// until all panicking threads have dumped their traces.
318 var panicking = std.atomic.Value(u8).init(0);330 var panicking = std.atomic.Value(u8).init(0);
319331
320 // Locked to avoid interleaving panic messages from multiple threads.
321 var panic_mutex = std.Thread.Mutex{};
322
323 /// Tracks the state of the current panic. If the code within the332 /// Tracks the state of the current panic. If the code within the
324 /// panic triggers a secondary panic, this allows us to recover.333 /// panic triggers a secondary panic, this allows us to recover.
325 threadlocal var panic_state_raw: PanicState = .{};334 threadlocal var panic_state_raw: PanicState = .{};
...@@ -387,7 +396,7 @@ const PanicSwitch = struct {...@@ -387,7 +396,7 @@ const PanicSwitch = struct {
387396
388 state.recover_stage = .release_ref_count;397 state.recover_stage = .release_ref_count;
389398
390 panic_mutex.lock();399 std.debug.lockStdErr();
391400
392 state.recover_stage = .release_mutex;401 state.recover_stage = .release_mutex;
393402
...@@ -447,7 +456,7 @@ const PanicSwitch = struct {...@@ -447,7 +456,7 @@ const PanicSwitch = struct {
447 noinline fn releaseMutex(state: *volatile PanicState) noreturn {456 noinline fn releaseMutex(state: *volatile PanicState) noreturn {
448 state.recover_stage = .abort;457 state.recover_stage = .abort;
449458
450 panic_mutex.unlock();459 std.debug.unlockStdErr();
451460
452 goTo(releaseRefCount, .{state});461 goTo(releaseRefCount, .{state});
453 }462 }
src/link/MachO.zig+1-1
...@@ -3230,7 +3230,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {...@@ -3230,7 +3230,7 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
3230 self.zig_text_seg_index = try self.addSegment("__TEXT_ZIG", .{3230 self.zig_text_seg_index = try self.addSegment("__TEXT_ZIG", .{
3231 .fileoff = off,3231 .fileoff = off,
3232 .filesize = filesize,3232 .filesize = filesize,
3233 .vmaddr = base_vmaddr + 0x8000000,3233 .vmaddr = base_vmaddr + 0x4000000,
3234 .vmsize = filesize,3234 .vmsize = filesize,
3235 .prot = macho.PROT.READ | macho.PROT.EXEC,3235 .prot = macho.PROT.READ | macho.PROT.EXEC,
3236 });3236 });
src/main.zig+5-6
...@@ -44,8 +44,7 @@ pub const std_options = .{...@@ -44,8 +44,7 @@ pub const std_options = .{
44 },44 },
45};45};
4646
47// Crash report needs to override the panic handler47pub const Panic = crash_report.Panic;
48pub const panic = crash_report.panic;
4948
50var wasi_preopens: fs.wasi.Preopens = undefined;49var wasi_preopens: fs.wasi.Preopens = undefined;
51pub fn wasi_cwd() std.os.wasi.fd_t {50pub fn wasi_cwd() std.os.wasi.fd_t {
...@@ -826,7 +825,6 @@ fn buildOutputType(...@@ -826,7 +825,6 @@ fn buildOutputType(
826 var version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 };825 var version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 };
827 var have_version = false;826 var have_version = false;
828 var compatibility_version: ?std.SemanticVersion = null;827 var compatibility_version: ?std.SemanticVersion = null;
829 var formatted_panics: ?bool = null;
830 var function_sections = false;828 var function_sections = false;
831 var data_sections = false;829 var data_sections = false;
832 var no_builtin = false;830 var no_builtin = false;
...@@ -1537,9 +1535,11 @@ fn buildOutputType(...@@ -1537,9 +1535,11 @@ fn buildOutputType(
1537 } else if (mem.eql(u8, arg, "-gdwarf64")) {1535 } else if (mem.eql(u8, arg, "-gdwarf64")) {
1538 create_module.opts.debug_format = .{ .dwarf = .@"64" };1536 create_module.opts.debug_format = .{ .dwarf = .@"64" };
1539 } else if (mem.eql(u8, arg, "-fformatted-panics")) {1537 } else if (mem.eql(u8, arg, "-fformatted-panics")) {
1540 formatted_panics = true;1538 // Remove this after 0.15.0 is tagged.
1539 warn("-fformatted-panics is deprecated and does nothing", .{});
1541 } else if (mem.eql(u8, arg, "-fno-formatted-panics")) {1540 } else if (mem.eql(u8, arg, "-fno-formatted-panics")) {
1542 formatted_panics = false;1541 // Remove this after 0.15.0 is tagged.
1542 warn("-fno-formatted-panics is deprecated and does nothing", .{});
1543 } else if (mem.eql(u8, arg, "-fsingle-threaded")) {1543 } else if (mem.eql(u8, arg, "-fsingle-threaded")) {
1544 mod_opts.single_threaded = true;1544 mod_opts.single_threaded = true;
1545 } else if (mem.eql(u8, arg, "-fno-single-threaded")) {1545 } else if (mem.eql(u8, arg, "-fno-single-threaded")) {
...@@ -3405,7 +3405,6 @@ fn buildOutputType(...@@ -3405,7 +3405,6 @@ fn buildOutputType(
3405 .force_undefined_symbols = force_undefined_symbols,3405 .force_undefined_symbols = force_undefined_symbols,
3406 .stack_size = stack_size,3406 .stack_size = stack_size,
3407 .image_base = image_base,3407 .image_base = image_base,
3408 .formatted_panics = formatted_panics,
3409 .function_sections = function_sections,3408 .function_sections = function_sections,
3410 .data_sections = data_sections,3409 .data_sections = data_sections,
3411 .no_builtin = no_builtin,3410 .no_builtin = no_builtin,
src/mutable_value.zig+2-2
...@@ -88,11 +88,11 @@ pub const MutableValue = union(enum) {...@@ -88,11 +88,11 @@ pub const MutableValue = union(enum) {
88 .ptr = (try s.ptr.intern(pt, arena)).toIntern(),88 .ptr = (try s.ptr.intern(pt, arena)).toIntern(),
89 .len = (try s.len.intern(pt, arena)).toIntern(),89 .len = (try s.len.intern(pt, arena)).toIntern(),
90 } }),90 } }),
91 .un => |u| try pt.intern(.{ .un = .{91 .un => |u| try pt.internUnion(.{
92 .ty = u.ty,92 .ty = u.ty,
93 .tag = u.tag,93 .tag = u.tag,
94 .val = (try u.payload.intern(pt, arena)).toIntern(),94 .val = (try u.payload.intern(pt, arena)).toIntern(),
95 } }),95 }),
96 });96 });
97 }97 }
9898
src/target.zig-8
...@@ -586,14 +586,6 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt...@@ -586,14 +586,6 @@ pub inline fn backendSupportsFeature(backend: std.builtin.CompilerBackend, compt
586 => true,586 => true,
587 else => false,587 else => false,
588 },588 },
589 .panic_unwrap_error => switch (backend) {
590 .stage2_c, .stage2_llvm => true,
591 else => false,
592 },
593 .safety_check_formatted => switch (backend) {
594 .stage2_c, .stage2_llvm => true,
595 else => false,
596 },
597 .error_return_trace => switch (backend) {589 .error_return_trace => switch (backend) {
598 .stage2_llvm => true,590 .stage2_llvm => true,
599 else => false,591 else => false,
test/cases/exit.zig+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1pub fn main() void {}1pub fn main() void {}
22
3// run3// run
4// target=x86_64-linux,x86_64-macos,x86_64-windows,x86_64-plan94// target=x86_64-linux,x86_64-macos,x86_64-windows
5//5//